Models

Class Client

class Client(models.Model):
    name = models.CharField('clients name', max_length=128, null=False)

Class Account

class Account(models.Model):
    iban = models.CharField('iban', max_length=10, null=False, unique=True)
    created = models.DateTimeField('creation date', auto_now_add=True)
    closed = models.DateTimeField('closed date', default=None, null=True)
    balance = models.FloatField('current balance', default=0, null=False)
    owner = models.ForeignKey(Client, null=False)

Class Transaction

class Transaction(models.Model):
    timestamp = models.DateTimeField('transaction timestamp', auto_now_add=True)
    src = models.ForeignKey('Account', default=None, null=True)
    dest = models.ForeignKey('Account', default=None, related_name='target', null=True)
    amount = models.FloatField('transaction amount', null=False)

Database Creation and Migration

Pre aplikovanie akejkoveľvek zmeny v modeli alebo modeloch je potrebné vykonať tzv. migráciu. Migrácia zabezpečí aktualizovanie databázovej schémy automaticky vzhľadom na vykonané zmeny bez nutnosti manuálneho zásahu do databázovej schémy (žiadne ručné ALTER TABLE)

$ ./manage.py makemigrations
$ ./manage.py migrate

Výsledok si môžeme priamo overiť v databáze spustením databázového klienta pomocou nástroja manage.py a jeho príkazu dbshell

$ ./manage.py db_shell
sqlite> .tables

First Steps

Budeme pracovať z príkazového riadku. Používať budeme príkaz shell_plus z nástroja manage.py, ktorý spustí ipython, pokiaľ je nainštalovaný a rovno nahrá aj všetky modely. To je značnou výhodou, nakoľko sa po spustení nemusíme vždy starať o naimportovanie potrebných balíčkov. Taktiež zabezpečí ich znovunačítanie, ak spravíme nejakú zmenu. Občas sa však jeho ukončeniu a znovuspusteniu nevyhneme.

$ ./manage.py shell_plus
SQLite version 3.14.2 2016-09-12 18:50:49
Enter ".help" for usage hints.
sqlite> .tables
account_account             auth_user_groups          
account_client              auth_user_user_permissions
account_transaction         django_admin_log          
auth_group                  django_content_type       
auth_group_permissions      django_migrations         
auth_permission             django_session            
auth_user                 
sqlite> .schema account_client
CREATE TABLE "account_client" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(128) NOT NULL);
sqlite>

Creating New Client

Vytvorenie nového klienta

client = Client()
client.name = 'jano'
client.id
None

Id (primárny kľúč klienta) začne existovať až potom, ako sa uloží do databázy:

client.save()
client.id
1

Vytvorenie nového klienta zadaním jeho vlastností priamo pri vytváraní

client = Client(name='juraj')
client.save()

Alebo ako one-liner

Client(name='jozef').save()

Checking Results in DB

Kedykoľvek si môžeme overiť výsledky snaženia priamo v databáze

Updating Existing Client

client.id
3
client.name = 'Jozef'
client.save()

Deleting Existing Client

client.delete()

Client Update

Aby sme pri vypisovani konkretneho objektu nevideli jeho reprezentacny tvar ako v prípade inštancie triedy Client

<Client: client object>

vytvoríme si tzv. magickú metódu s názvom __str__(), ktorá sa bude volať vždy, keď budeme chcieť reťazcovú reprezentáciu daného objektu. Jej návratovou hodnotou je totiž reťazec:

def __str__(self):
   return '{}: {}'.format(self.id, self.name)

Account Methods

Vytvorte magickú funkciu __str__(), ktorá vráti reťazcovú reprezentáciu objektu

def __str__(self):
    return '{} ({}) {}'.format(self.iban, self.owner.name, self.balance)

Vytvorte metódu is_open(), ktorá vráti hodnotu True, ak je účet otvorený alebo False, ak nie je

def is_open(self):
    return self.closed is None

Vytvorte metódu is_closed(), ktorá vráti hodnotu True, ak je účet zatvorený alebo False, ak zatvorený nie je

def is_closed(self):
    return not self.is_open()

Vytvorte metódu withdraw(), pomocou ktorej zabezpečíte výber požadovanej čiastky z účtu. Prečerpanie účtu riešiť nemusíte, ale výber zabezpečte len v prípade, že je účet otvorený. Ak nie je, skončite s výnimkou týpu ValueErrorPo úspešnom výbere vytvorte transakciu, v ktorej uvediete zdrojový účet, z ktorého sú peniaze vyberané a množstvo peňazí, ktoré sú vyberané.

def withdraw(self, amount):
    if self.is_closed():
        raise ValueError('Account is closed')

    self.balance -= amount
    self.save()

    # make transaction
    Transaction(src=self, amount=amount).save()

Vytvorte metódu deposit(), pomocou ktorej zabezpečíte vklad požadovanej čiastky na účet. Tú však bude možné vložiť len v prípade, ak účet nie je zatvorený. Ak je, skončite s výnimkou typu ValueErrorPo úspešnom vklade vytvorte transakciu, v ktorej uvediete cieľový účet, na ktorý sú peniaze vkladané a ich množstvo.

def deposit(self, amount):
    if self.is_closed():
        raise ValueError('Account is closed')

    self.balance += amount
    self.save()

    # make transaction
    Transaction(dest=self, amount=amount).save()

Vytvorte metódu transfer(), pomocou ktorej budete vedieť previesť peniaze z jedného účtu na druhý. Samozjreme prevod bude možný len v tom prípade, ak účet nie je zatvorený. Samozrejme pre túto operáciu vytvorte samostatnú inštanciu triedy Transakcia, kde túto transakciu opíšete.

def transfer(self, dest, amount):
    # check if accounts are open first
    if self.is_closed():
        raise ValueError('Source Account is Closed')

    if dest.is_closed():
        raise ValueError('Destination Account is Closed')

    self.amount -= amount
    self.save()
    dest.amount += amount
    dest.save()

    # make transaction
    Transaction(src=self, dest=dest, amount=amount).save()

Transaction Methods

Vytvorte magickú metódu __str__(), ktorá vráti reťazcovú reprezentáciu transakcie. A to tak, že:

  • ak nie je zadaný cieľový účet, vráťte reťazec s informáciami o výbere (withdraw)
  • ak nie je zadaný zdrojový účet, vráťte reťazec s informáciami o vklade (deposit)
  • ak sú zadané oba účty, vráťte reťazec s informáciami o prenose (transfer)
def __str__(self):
    if self.src is None:
        return 'deposit to {} at {}: {}'.format(self.dest, self.timestamp, self.amount)
    elif self.dest is None:
        return 'withdraw from {} at {}: {}'.format(self.src, self.timestamp, self.amount)
    else:
        return 'transaction from {} to {} at {}: {}'.format(self.src, self.dest, self.timestamp, self.amount)

TODO

  • Model.objects.all()
  • Model.objects.get()
  • urobit ulohy podla toho, co bude treba:
    • ziskat vsetky ucty
    • ziskat ucty len daneho (prihlaseneho) pouzivatela
    • ziskat transakcie len s prislusnym uctom
    • ziskat transakcie len daneho (prihlaseneho) pouzivatela
  • validacia formularu

results matching ""

    No results matching ""