Polje „omiljeni“
Dodaj modelu polje omiljeni (da/ne, podrazumevano ne), napravi i primeni migraciju i prikaži polje u admin listi, sa mogućnošću menjanja direktno u listi.
Da bi se logoi čuvali, Django mora da zna kako izgleda jedan logo: naziv, slogan, boja, oblik, font i ko je vlasnik. To opisujemo modelom – Python klasom iz koje Django sam pravi tabelu u bazi. Zatim ga uključujemo u admin panel i isprobavamo upite iz Python-a.
# logoi/models.py
from django.conf import settings
from django.core.validators import RegexValidator
from django.db import models
class Logo(models.Model):
OBLICI = [("krug", "krug"), ("kvadrat", "kvadrat"), ("romb", "romb")]
FONTOVI = [
("Arial, sans-serif", "Arial"),
("Georgia, serif", "Georgia"),
("'Courier New', monospace", "Courier New"),
]
vlasnik = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="logoi")
naziv = models.CharField(max_length=20)
slogan = models.CharField(max_length=30, blank=True)
boja = models.CharField(max_length=7, default="#dd0022",
validators=[RegexValidator(r"^#[0-9a-fA-F]{6}$", "Boja mora biti oblika #RRGGBB.")])
oblik = models.CharField(max_length=10, choices=OBLICI, default="krug")
font = models.CharField(max_length=40, choices=FONTOVI, default="Arial, sans-serif")
napravljen = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-napravljen"] # najnoviji prvi
def __str__(self):
return f"{self.naziv} ({self.vlasnik})"
def inicijali(self):
"""'Sekcija Pupin' -> 'SP', 'Logo' -> 'LO' (isto kao u generator.js)."""
reci = self.naziv.split()
if not reci:
return "?"
if len(reci) == 1:
return reci[0][:2].upper()
return (reci[0][0] + reci[1][0]).upper()
| Polje | Tip | Značenje |
|---|---|---|
vlasnik | ForeignKey | veza ka korisniku; on_delete=CASCADE – brisanjem korisnika brišu se i njegovi logoi; related_name="logoi" omogućava korisnik.logoi.all() |
naziv, slogan | CharField | tekst ograničene dužine; blank=True – može biti prazno |
boja | CharField + validator | dozvoljen samo zapis #RRGGBB |
oblik, font | CharField + choices | samo vrednosti sa spiska – u formi postaje padajuća lista |
napravljen | DateTimeField(auto_now_add=True) | vreme se upiše samo pri pravljenju |
Svaki model dobija i polje id (redni broj, primarni ključ) automatski. Vrednosti u choices i polja su ista kao u generatoru iz frontend projekta.
python manage.py makemigrations
python manage.py migrate
makemigrations uporedi modele sa stanjem baze i zapiše izmenu u logoi/migrations/0001_initial.py; migrate je primeni na bazu. Kada kasnije promeniš model (npr. dodaš polje), ponoviš obe komande. SQL ne pišeš ručno – ali ga možeš videti: python manage.py sqlmigrate logoi 0001.
# logoi/admin.py
from django.contrib import admin
from .models import Logo
@admin.register(Logo)
class LogoAdmin(admin.ModelAdmin):
list_display = ("naziv", "vlasnik", "oblik", "boja", "napravljen")
list_filter = ("oblik", "napravljen")
search_fields = ("naziv", "slogan", "vlasnik__username")
Posle ovoga u /admin/ postoji tabela Logos sa kolonama, filterom po obliku i datumu i pretragom. Dodaj nekoliko logoa ručno – trebaće za sledeće korake.
Ime u adminu se lepše prikazuje ako u class Meta dodaš verbose_name = "logo" i verbose_name_plural = "logoi".
python manage.py shell
>>> from django.contrib.auth.models import User
>>> from logoi.models import Logo
>>> ana = User.objects.get(username="ana")
>>> Logo.objects.create(vlasnik=ana, naziv="Sekcija Pupin", boja="#1f5f91", oblik="romb")
<Logo: Sekcija Pupin (ana)>
>>> Logo.objects.count()
1
>>> ana.logoi.all() # svi logoi korisnice ana
<QuerySet [<Logo: Sekcija Pupin (ana)>]>
>>> Logo.objects.filter(oblik="krug").count() # WHERE oblik = 'krug'
0
>>> Logo.objects.filter(naziv__icontains="pupin") # sadrži "pupin", bez obzira na velika slova
<QuerySet [<Logo: Sekcija Pupin (ana)>]>
>>> l = Logo.objects.first(); l.inicijali()
'SP'
>>> l.slogan = "Programiramo"; l.save() # izmena
>>> l.delete() # brisanje
(1, {'logoi.Logo': 1})
| ORM | SQL (otprilike) |
|---|---|
Logo.objects.all() | SELECT * FROM logoi_logo |
.filter(oblik="krug") | WHERE oblik = 'krug' |
.order_by("-napravljen") | ORDER BY napravljen DESC |
.create(...) / .save() | INSERT / UPDATE |
.delete() | DELETE |
ORM (Object-Relational Mapping) pretvara Python izraze u SQL i uvek koristi parametre – zato je otporan na SQL injekciju iz lekcije Bezbednost.
U videu se baza odmah prebacuje na PostgreSQL instaliran na računaru. U ovoj verziji projekta za razvoj ostajemo na SQLite-u, a PostgreSQL koristimo tek na serveru.
Za svaki zadatak postoji primer, uputstvo i rešenje.
Dodaj modelu polje omiljeni (da/ne, podrazumevano ne), napravi i primeni migraciju i prikaži polje u admin listi, sa mogućnošću menjanja direktno u listi.
makemigrations pa migrate. Greška no such column znači da je migracija zaboravljena.Logo.objects.get(...) baca grešku ako nema rezultata ili ih ima više; za „možda nema“ koristi filter(...).first().1. Šta radi python manage.py makemigrations?
2. Šta znači related_name="logoi" u ForeignKey?
3. Zašto je ORM otporan na SQL injekciju?
| Parametri baze podataka se podešavaju u okviru settings.py fajla aplikacije. Podrazumevana baza je SQLite baza, ali se može podesiti i neka druga za podrazumevanu bazu. Takođe se može koristitii više baza u okviru Django projekta i onda se to mora naznačiti u settings.py fajlu. Da bi se podesila baza SQLite3 ili Postgresql u settings.py treba podesiti : |
Django aplikacija-Kreiranje baze-video |
Vidi se da konekcija sa bazom nije mogla da se uspostavi, jer baza nije ni kreirana. Dakle, sledeći korak je kreiranje baze. Posle instaliranja postgresql baze podataka, kreiranja korisnika za bazu i postavljanja šifre, dalje treba kreirati bazu za aplikaciju logo creator, koju ćemo nazvati 'logo_kreator_baza' što je već i definisano u settings.py.
Posle konektovanja na pgAdminServer treba kreirati novu bazu desnim klikom na databases a zatim klikom na dugme create, kao što se vidi na sledećoj slici:
Kada se kreira baza “logo_kreator_baza”, koja je prazna, nema još uvek ni jednu tabelu, može se startovati server aplikacije logo kreator na localhost-u i ovoga puta se neće prikazati greška.
Posle kreiranja baze:
Da bi startovali prvi put admin interfejs potrebno inicijalizovati bazu. Podrazumeva se da je prethodno u settings.py fajlu podešena baza kako je ranije opisano. Dakle, komanda:
Posle prijavljivanja prikazaće se admin deo sajta:
Ovde se može upravljati grupama i korisnicima al ii tabelama koje se budu definisale u modelu.| Prethodno |<Logo Kreator - Kreiranje Naslovne strane |
Sledeće Kreiranje aplikacije na Heroku Web Platformi>| |