Django ORM

97 views
Skip to first unread message

PavelZet

unread,
Aug 14, 2018, 4:59:17 AM8/14/18
to django-cs
Ahoj, chci se zeptat, zda 

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?
2) jak lze určit zda použít INNER nebo OUTER JOIN ?
3) když chci vyhledat entitu s posledním ID, tak nejlepší volbou je forma 
SELECT ... WHERE id = max(id)
jak ji dosáhnu?
zkoušel sem .filter(id=Max(id)), který ale použije pomalejší HAVING místo optimálního WHERE
SELECT ... HAVING id = max(id)
4) proč všichni používají zápis .latest() (resp. .order_by(id)[:1].get()), který srovná celou tabulku a vybere poslední prvek formou
SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?
5) existuje nějaký dobrý tutoriál z pohledu SQL, kde jasně uvidím jak psát ORM formu, abych dosáhl konkrétního SQL ?
6) napíšu v ORM obecně jakkoli zamotaný SQL dotaz? nebo sou věci které prostě nejdou?
7) jsou případy na které se Django ORM vyloženě nehodí a musí se použít náhradní řešení ?

Jsem zvyklý si optimalizované SQL dotazy psát sám. Samotný dotaz mám napsaný rychle.
Nevýhoda byla, že musím myslet na escapování vstupů a poté musím mapovat výsledné pole na entitu. Toho bych se rád z časových důvodů zbavil.
Na to se hodí ORM.

V ORM řešení mám vše napsané rychle a funkčně, to je fajn a jeví se dobře.
ALE poté musím dotazy ještě debugovat, googlit a editovat tak, aby vznikl optimální SQL dotaz, jaký si představuju. Takže časová úspora je zase tatam :(

Díky za reakce znalých.

Honza Král

unread,
Aug 14, 2018, 5:52:59 AM8/14/18
to djan...@googlegroups.com
On Tue, Aug 14, 2018 at 10:59 AM PavelZet <zeh...@gmail.com> wrote:
Ahoj, chci se zeptat, zda 

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

Ahoj, vsichni urcite ne, ale lide co pracuji s Djangem vetsinou ORM pouzivaji.

2) jak lze určit zda použít INNER nebo OUTER JOIN ?

Tohle si primarne Django ORM urcuje sam podle toho, o co si pozadal. Princip ORM je od toho aby uzivatele odstinila od syroveho SQL a mezi to patri i takovehle veci. Mas nejaky konkretni priklad kde ORM rozhodlo pro tvuj pripad spatne?

 
3) když chci vyhledat entitu s posledním ID, tak nejlepší volbou je forma 
SELECT ... WHERE id = max(id)
jak ji dosáhnu?
zkoušel sem .filter(id=Max(id)), který ale použije pomalejší HAVING místo optimálního WHERE
SELECT ... HAVING id = max(id)

Jsem zmateny - SELECT ... WHERE is = max(id) neni pro vetsinu databazi validni konstrukce a k vyzvednuti posledniho zaznamu nefunguje, overoval jsem pro postgres, pamatuju si neco spatne a mas tuhle konstrukci vyzkousenou? Na jake databazi?
 
4) proč všichni používají zápis .latest() (resp. .order_by(id)[:1].get()), který srovná celou tabulku a vybere poslední prvek formou
SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?

Doporucil bych se podivat na provadeci plan ve tve databazi, ale silne pochybuju, ze jakakoliv databaze bude srovnavat celou tabulku kdyz chci jen jeden prvek. Obzvlast kdyz mam nad polickem id index, v tom pripade se jedna o trivialni pristup k tomu indexu a iteraci pres nej s LIMIT 1.
 
5) existuje nějaký dobrý tutoriál z pohledu SQL, kde jasně uvidím jak psát ORM formu, abych dosáhl konkrétního SQL ?

opet - tohle popira byhody ORM, jestli chces psat vlastni SQL, pis vlastni SQL, nemelo by to ale byt vubec potreba.

6) napíšu v ORM obecně jakkoli zamotaný SQL dotaz? nebo sou věci které prostě nejdou?

Jsou samozrejme veci ktere jeste nejdou primo pres ORM ale mas vzdy k dispozici metodu raw (0) ktera ti umozni napsat si kompletne svuj SQL dotaz.

 
7) jsou případy na které se Django ORM vyloženě nehodí a musí se použít náhradní řešení ?

z prakticke zkusenosti o zadnem pripadu nevim ale urcite se nejake najdou. Pro me je to casto signal, ze se neco nedeje
 

Jsem zvyklý si optimalizované SQL dotazy psát sám. Samotný dotaz mám napsaný rychle.
Nevýhoda byla, že musím myslet na escapování vstupů a poté musím mapovat výsledné pole na entitu. Toho bych se rád z časových důvodů zbavil.
Na to se hodí ORM.
Ne, ORM je o necem skutecne jinem. Na escapovani je proste db api ktere ti escapuje vstupy zcela automaticky pokud ho pouzivas spravne - s parametery -  a nelepis vysledny SQL dotaz jako string. To neni NIKDY akceptovatelne reseni.

Mapovani na entitu muzes delat nezavisle.

V ORM řešení mám vše napsané rychle a funkčně, to je fajn a jeví se dobře.
ALE poté musím dotazy ještě debugovat, googlit a editovat tak, aby vznikl optimální SQL dotaz, jaký si představuju. Takže časová úspora je zase tatam :(

Opet nejaky konkretni pripad kde django vygenerovalo dotaz ktery je radove min efektivni nez to, co si z nej pak udelal? Bez takovych prikladu je tohle akademicka diskuze kde cisla nejsou na tve strane - Django ORM pouziva naprosto drtiva vetsina Django webu bez vetsich problemu...


Díky za reakce znalých.

--
--
E-mailová skupina djan...@googlegroups.com
Správa: http://groups.google.cz/group/django-cs
---
Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny „django-cs“ ve Skupinách Google.
Chcete-li zrušit odběr skupiny a přestat dostávat e-maily ze skupiny, zašlete e-mail na adresu django-cs+...@googlegroups.com.
Chcete-li tuto diskusi zobrazit na webu, navštivte https://groups.google.com/d/msgid/django-cs/879de872-c7c6-4aad-b00f-d9a9a58f6ae9%40googlegroups.com.
Další možnosti najdete na https://groups.google.com/d/optout.

Jirka Vejrazka

unread,
Aug 14, 2018, 5:53:38 AM8/14/18
to django-cs
Ahoj,

  ja nejsem 100% vyvojar a programator, ale Django ORM pouzivam uz cca 10 let, tak se k tomu vyjadrim :)

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

  Nevim, jestli vsichni :)  Ale hodne. Muzes pouzit treba sqlalchemy, pokud vim. Jen to myslim nefunguje s Django Admin (ktery nepouzivam).

2) jak lze určit zda použít INNER nebo OUTER JOIN ?

  Nevim, nepotreboval jsem.

3) když chci vyhledat entitu s posledním ID, tak nejlepší volbou je forma 
SELECT ... WHERE id = max(id)
jak ji dosáhnu?
zkoušel sem .filter(id=Max(id)), který ale použije pomalejší HAVING místo optimálního WHERE
SELECT ... HAVING id = max(id)

  Nejlepsi volbou je to, co bez problemu funguje. ORM nema byt lepsi nez ciste SQL - ma byt univerzalnejsi a jednodussi na psani. Pokud umis SQL dobre (a vypada to, ze jo), tak muzes pouzit ve vetsine pripadu .raw() a dostat, co potrebujes. 

  Pro mne osobne je jedno, jestli ORM pouzije "WHERE" nebo "HAVING" - nemeril jsem to, ale vzhledem k tomu, ze sloupec "id" byva povetsinou indexovany, tak jsou pro me pouziti rozdily v rychlosti mezi temi dvema nezajimave.

  Ber to tak, ze ORM musi zvladnout vice typu databazi s mirne odlisnymi syntaxemi. Je to kompromis mezi rychlosti vyvoje, pokrytim ruznych DB enginu a optimalnosti dotazu pro jednotlive DB enginy. Mozna bys chtel, aby ten kompromis byl posunuty vice k jednomu z tech bodu. Pak mas dve moznosti - bud zkusit jine ORM nebo to stavajici zkusit vylepsit (patche vitany).

4) proč všichni používají zápis .latest() (resp. .order_by(id)[:1].get()), který srovná celou tabulku a vybere poslední prvek formou
SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?

  Viz vyse. Pokud je sloupec indexovan, nevidim to jako problem.

5) existuje nějaký dobrý tutoriál z pohledu SQL, kde jasně uvidím jak psát ORM formu, abych dosáhl konkrétního SQL ?

  V dokumentaci se pise, ze pokud ti z nejakeho duvodu nevyhovuje SQL vyrobene ORM, muzes pouzit .raw(). Nevim o tom, ze by existovalo "z tohoto SQL mi zpetne poskladej ORM dotaz".

6) napíšu v ORM obecně jakkoli zamotaný SQL dotaz? nebo sou věci které prostě nejdou?

  Ne a ano.

7) jsou případy na které se Django ORM vyloženě nehodí a musí se použít náhradní řešení ?

  Cokoli komplikovaneho. ORM se zlepsuje (pamatuju doby, kdy neumelo treba F() funkce), ale dokonale neni. Pokryje 80% az 90% "beznych" veci (pro kazdeho to znamena neco jineho). Speciality si musi zaridit kazdy sam.

  Jirka

Martin Kubát

unread,
Aug 14, 2018, 5:59:10 AM8/14/18
to djan...@googlegroups.com
Zdravím,
  1. django ORM je první volba. Django je tímto úzce spjato. Bude určitě existovat nějaká knihovna, která umí django+SQLAlchemy, ale moc bych na to nevsázel. To už je pak lepší flask + SQLAlchemy.
  2. nevím o tom, ORM si toto řídí dle druhu vazby
  3. viz 4.
  4. asi zalezi na db enginu, ale na postgresu SELECT ... WHERE id = max(id) udělat nelze. Musis group by id a pak having, a to je rozhodne delsi, nez order by id. Na id je standardne index.
  5. asi jo, ale nedokazu poradit
  6. nektere veci proste nejdou, resi se to https://docs.djangoproject.com/pl/2.1/topics/db/sql/#performing-raw-sql-queries, nebo nizkourovnove primo sql.
  7. určitě. django ORM je jednoduché, i kdyz v posledních letech toho umí více a více. Na SQLAlchemy ale jestě úplně nemá. Namátkou nativní polymorfismus.
Debugovat dotazy z ORM je urcite dobre a po nejake praxi se i v ramci ORM budou psat dotazy rychleji a spravne.

Hodně zdaru.
MK



út 14. 8. 2018 v 10:59 odesílatel PavelZet <zeh...@gmail.com> napsal:
--

Jan Walter

unread,
Aug 14, 2018, 6:32:54 AM8/14/18
to djan...@googlegroups.com
Nebudu opakovat již vyřčené, jen Ti můžu říct z pohledu člověka, který kdysi s SQL strávil hodně času a měl ho moc rád, že Django má ORM api moc hezký, zvykneš si rychle, a ujetej sql jazyk už nebudeš chtít pro běžný situace používat. Je to mnohem čitelnější, rychlejší na použití.

Zkus a uvidíš.

Btw, dobře nastavený indexy, integritní omezení, konfiguraci db atp. potřebuješ v obou případech.

starenka .

unread,
Aug 14, 2018, 6:35:50 AM8/14/18
to djan...@googlegroups.com
Ostatni byli rychlejsi, tak jen pripomenu, ze dotazy neni treba "debugovat", ale staci 'print(qs.query)'.

-----
'aknerats'[::-1]

Vítek Pliska

unread,
Aug 14, 2018, 8:12:46 AM8/14/18
to djan...@googlegroups.com
Já doplním že v posledním djangu je snad i explain.

Plus za mě jen print query moc nestačí, v debug toolbaru oceňuji např zobrazení duplicitních dotazů což mi říká kde mi chybí select_related, kam by bylo dobré dát prefetch e explain je tam také přehledný.

V. 

Dne út 14. 8. 2018 12:35 uživatel starenka . <star...@gmail.com> napsal:

Václav Dohnal

unread,
Aug 15, 2018, 3:58:02 AM8/15/18
to django-cs
Ještě doplním, že na ladění SQL/ORM se mi osvědčil python manage.py shell_plus --print-sql z knihovny https://github.com/django-extensions/django-extensions.

Dne úterý 14. srpna 2018 14:12:46 UTC+2 Vítek Pliska napsal(a):

starenka .

unread,
Aug 15, 2018, 4:04:08 AM8/15/18
to djan...@googlegroups.com
Dik, to je fajn... :)

Ad django debug toolbar: asi fajn, ale ne vzdycky mas viewcka/neco renderujes v browseru...

-----
'aknerats'[::-1]

Petr Messner

unread,
Aug 15, 2018, 4:22:23 AM8/15/18
to djan...@googlegroups.com
Ahoj,

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

já teda nejsem Djangista, ale co jsem tak vypozoroval, tak Django ORM je základní abstrakce pro data store a business logiku, díky tomu funguje integrace s pluginy, adminem a tak. Když vezmeš Django a odečteš ORM a cokoliv, co na ORM nějak navazuje, tak ti zbyde Flask :) Takže potom by vlastně Django nedávalo žádnou přidanou hodnotu a z toho bych usoudil, že 99,9% Django vývojářů bude používat ORM :)

V kontextu tohohle je psaní vlastních SQL příkazů asi něco jako programovat v C, když můžu to samé naprogramovat v Pythonu. Ale i to je někdy potřeba.

SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?

Z čeho tak usuzuješ? Nevím o ničem rychlejším, než vlézt do id indexu, podívat se na poslední prvek (předpokládám, že ten index je seřazený), a fetchnout záznam, na který ten poslední prvek odkazuje. Nebo aspoň to si představuju, že SQL databáze udělá. Aspoň teda NoSQL databáze to tak dělají :)

K debugování SQL dotazů apod. bych rád zmínil, že je fajn monitorovat aplikaci "zvenčí" - zapnout slow log v databázi, monitorovat pomalé requesty (např. nginx může do access logu uvádět celkovou dobu trvání requestu). Blackbox přístup mi tady přijde obecně robustnější než whitebox.

Možná by bylo zajímavé v dev a staging prostředí uměle zvýšit latenci mezi appkou a databází, protože každá prasárna fungovala dobře, když běžela u vývojáře na localhostu :) 

Nebo přidat do testů nějaký middleware, který bude hlídat metriky okolo SQL dotazů.

Nevýhoda byla, že musím myslet na escapování vstupů a poté musím mapovat výsledné pole na entitu. Toho bych se rád z časových důvodů zbavil.

Jsi programátor. Když na něco musíš myslet, tak to znamená, že sis na to nenapsal pomocnou funkci, nebo máš špatnou abstrakci.

Petr Messner


út 14. 8. 2018 v 10:59 odesílatel PavelZet <zeh...@gmail.com> napsal:
Ahoj, chci se zeptat, zda 
SELECT ... WHERE id = max(id)
jak ji dosáhnu?
zkoušel sem .filter(id=Max(id)), který ale použije pomalejší HAVING místo optimálního WHERE
SELECT ... HAVING id = max(id)
4) proč všichni používají zápis .latest() (resp. .order_by(id)[:1].get()), který srovná celou tabulku a vybere poslední prvek formou
SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?
5) existuje nějaký dobrý tutoriál z pohledu SQL, kde jasně uvidím jak psát ORM formu, abych dosáhl konkrétního SQL ?
6) napíšu v ORM obecně jakkoli zamotaný SQL dotaz? nebo sou věci které prostě nejdou?
7) jsou případy na které se Django ORM vyloženě nehodí a musí se použít náhradní řešení ?

Jsem zvyklý si optimalizované SQL dotazy psát sám. Samotný dotaz mám napsaný rychle.
Nevýhoda byla, že musím myslet na escapování vstupů a poté musím mapovat výsledné pole na entitu. Toho bych se rád z časových důvodů zbavil.
Na to se hodí ORM.

V ORM řešení mám vše napsané rychle a funkčně, to je fajn a jeví se dobře.
ALE poté musím dotazy ještě debugovat, googlit a editovat tak, aby vznikl optimální SQL dotaz, jaký si představuju. Takže časová úspora je zase tatam :(

Díky za reakce znalých.

--

Jan Bednařík

unread,
Aug 16, 2018, 10:09:01 AM8/16/18
to djan...@googlegroups.com

st 15. 8. 2018 v 10:22 odesílatel Petr Messner <petr.m...@gmail.com> napsal:
Ahoj,

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

já teda nejsem Djangista, ale co jsem tak vypozoroval, tak Django ORM je základní abstrakce pro data store a business logiku, díky tomu funguje integrace s pluginy, adminem a tak. Když vezmeš Django a odečteš ORM a cokoliv, co na ORM nějak navazuje, tak ti zbyde Flask :) Takže potom by vlastně Django nedávalo žádnou přidanou hodnotu a z toho bych usoudil, že 99,9% Django vývojářů bude používat ORM :)

Django je sada modulů co dobře spolupracují, ale není podmínka používat vše. Hodně věcí dokáže využít modely, ale Django se dá dobře používat i bez nich. Dělám na jedné aplikaci, která nepoužívá modely, ale jen views, formuláře, templaty, atp. Začal jsem s Flaskem, ale stejně jsem nakonec skončil u Djanga, protože tam ty věci spolu jednoduše fungují.

Honza

PavelZet

unread,
Sep 2, 2018, 3:56:26 AM9/2/18
to django-cs


Dne středa 15. srpna 2018 10:22:23 UTC+2 Messa napsal(a):
Ahoj,

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

já teda nejsem Djangista, ale co jsem tak vypozoroval, tak Django ORM je základní abstrakce pro data store a business logiku, díky tomu funguje integrace s pluginy, adminem a tak. Když vezmeš Django a odečteš ORM a cokoliv, co na ORM nějak navazuje, tak ti zbyde Flask :) Takže potom by vlastně Django nedávalo žádnou přidanou hodnotu a z toho bych usoudil, že 99,9% Django vývojářů bude používat ORM :)


Django ORM má zastat funkce dolování dat a business? Takže nemá smysl psát další vrstvy jako repository (dolování dat) a service (business logika) ? Veškerá logika má tedy být v jednom dlouhém view (pro každý modul)?
Asi bych i tak tyto vrstvy (repository a service) zachoval. Přijde mi přehlednější když views pouze zpracuje request a pak zavolá service. Views se tak dost zúží.
 
V kontextu tohohle je psaní vlastních SQL příkazů asi něco jako programovat v C, když můžu to samé naprogramovat v Pythonu. Ale i to je někdy potřeba.

SELECT ... ORDER BY id DESC LIMIT 1
což je pomalejší a obecně o něco horší možnost ?

Z čeho tak usuzuješ? Nevím o ničem rychlejším, než vlézt do id indexu, podívat se na poslední prvek (předpokládám, že ten index je seřazený), a fetchnout záznam, na který ten poslední prvek odkazuje. Nebo aspoň to si představuju, že SQL databáze udělá. Aspoň teda NoSQL databáze to tak dělají :)

ano, pravda, omlouvám se za desinformaci. 

PavelZet

unread,
Sep 2, 2018, 4:38:18 AM9/2/18
to django-cs
6) napíšu v ORM obecně jakkoli zamotaný SQL dotaz? nebo sou věci které prostě nejdou?

Konkrétní příklad, na který v ORM nemůžu přijít:
Mám 2 tabulky: 

terms (podmínky)
- id
- enable (příznak zda jsou podmínky aktivní)
- version (označení verze)

termslang (jejich jazykové mutace)
- id
- terms_id (vztah 1:N do tabulky terms, kde jedny podmínky mohou mít více překladů)
- lang (jazyková mutace; 1=cs, 2=en)
- source_html (text překladu)

Potřeboval bych napsat v ORM, abych jedním SQL dotazem vyzvedl nejnovější licenční podmínky (terms) a k nim odpovídající překlad (termslang).

V SQL bych to napsal takto:
SELECT terms.*, termslang.*
FROM terms
LEFT JOIN termslang ON
(terms.id = termslang.terms_id)
WHERE terms
.enable=1 AND termslang.lang=1
ORDER
by terms.id DESC
LIMIT
1

Modely jsem navrhl takto:

LANG_CHOICES = {
   
'cs': (1, _('cs')),
   
'en': (2, _('en')),
}

ENABLE_CHOICES
= (
   
(0, _('enabled')),
   
(1, _('disabled')),
)

class TermsLang(models.Model):
   
""" Terms translation """

    terms
= models.ForeignKey('Terms', verbose_name=_('terms of use'), on_delete=models.SET_NULL, null=True)
    lang
= models.PositiveSmallIntegerField(verbose_name=_('lang'), choices=LANG_CHOICES.values(), db_index=True)
    source_html
= RichTextField(verbose_name=_('terms source'), blank=True)
    create_time
= models.DateTimeField(_('create time'), auto_now_add=True)
    update_time
= models.DateTimeField(_('update time'), auto_now=True, null=True)

   
class Meta:
        verbose_name
= _('Localized terms of use')
        verbose_name_plural
= _('Localized terms of use')
        unique_together
= ('terms', 'lang')

class Terms(models.Model):
   
""" Terms of use """

    enable
= models.PositiveSmallIntegerField(verbose_name=_('enable'), choices=ENABLE_CHOICES, db_index=True)
    version
= models.CharField(_('version'), max_length=20)
    create_time
= models.DateTimeField(_('create time'), auto_now_add=True)
    update_time
= models.DateTimeField(_('update time'), auto_now=True, null=True)

   
class Meta:
        verbose_name
= _('Terms of use')
        verbose_name_plural
= _('Terms of use')


Jak ale přes Django ORM (ve views.py) optimálně vytáhnu entitu terms se svým překladem v jednom SQL dotazu ???

PavelZet

unread,
Sep 2, 2018, 4:54:45 AM9/2/18
to django-cs
žádné z řešení co mě napadá není optimální

a) přes terms :), ale 2 selecty a dlouhý kód :(
def terms(request):

   
try:
        terms_entity
= models.Terms.objects.filter(enable=1).latest('id')
        terms_id
= terms_entity.id
        terms_lang_entity
= models.TermsLang.objects.filter(terms_id=terms_id, lang=1).get()
        terms_html
= terms_lang_entity.source_html
   
except (models.Terms.DoesNotExist, models.TermsLang.DoesNotExist):
        terms_html
= ""

   
return render(request, 'terms.html', {'terms_html': terms_html})

b) přes terms_lang :(, jedním selectem :), krátký kód :)
def terms(request):

   
try:
        terms_lang_entity
= models.TermsLang.objects.select_related('terms').filter(lang=1, terms__enable=1).latest('terms__id')
        terms_html
= terms_lang_entity.source_html
   
except models.TermsLang.DoesNotExist:
        terms_html
= ""

   
return render(request, 'terms.html', {'terms_html': terms_html})

c) přes terms :), jedním selectem :), krátký kód :), ale nefunguje, protože model Terms v sobě neobsahuje žádný odkaz na TermsLang :(
def terms(request):

    terms_entity
= models.Terms.objects.select_related('termslang').filter(enable=1, termslang__lang=1).latest('id')
    terms_html
= terms_entity.termslang.source_html

   
return render(request, 'terms.html', {'terms_html': terms_html})

Prosím o náznak řešení v Django ORM


Dne neděle 2. září 2018 10:38:18 UTC+2 PavelZet napsal(a):

Honza Král

unread,
Sep 2, 2018, 11:21:38 AM9/2/18
to djan...@googlegroups.com
On Sun, Sep 2, 2018 at 9:56 AM PavelZet <zeh...@gmail.com> wrote:


Dne středa 15. srpna 2018 10:22:23 UTC+2 Messa napsal(a):
Ahoj,

1) opravdu všichni pro výběr dat z databáze používáte Django ORM ?

já teda nejsem Djangista, ale co jsem tak vypozoroval, tak Django ORM je základní abstrakce pro data store a business logiku, díky tomu funguje integrace s pluginy, adminem a tak. Když vezmeš Django a odečteš ORM a cokoliv, co na ORM nějak navazuje, tak ti zbyde Flask :) Takže potom by vlastně Django nedávalo žádnou přidanou hodnotu a z toho bych usoudil, že 99,9% Django vývojářů bude používat ORM :)


Django ORM má zastat funkce dolování dat a business? Takže nemá smysl psát další vrstvy jako repository (dolování dat) a service (business logika) ? Veškerá logika má tedy být v jednom dlouhém view (pro každý modul)?
Asi bych i tak tyto vrstvy (repository a service) zachoval. Přijde mi přehlednější když views pouze zpracuje request a pak zavolá service. Views se tak dost zúží.

business logika rozhodne nema byt ve views, ale na modelu. Netusim, jak do toho zapada Repository a co to ma spolecneho z dolovanim dat, muzes to trochu rozvest?
 

PavelZet

unread,
Sep 2, 2018, 1:14:14 PM9/2/18
to django-cs
Django je založen na třívrstvém modelu MVC.
Tedy v modulech (aplikacích) defaultně vytváří vrstvy:
models (M) -> views (C) -> a přidáváme ještě templates (V)
V Django asi bývá zvykem všechnu logiku zahrnout do modelů a hotovo.

Obecně při vývoji není dobré psát dlouhé špagetové soubory (soubor a třída do 200 řádků, funkce do 40 řádků), avšak pro větší moduly tyto tři vrstvy budou málo.
Já to řeším mj. dalšími vrstvami repository a service.
model -> repository -> service -> view -> template

model: definuje jen jak entity dat vypadají, jaké mají vztahy atp., prakticky obsahuje jen fields a meta
repository: zahrnuje veškerou logiku úložiště (jako režii s SQL, soubory, sítí, pamětí...) a ukládá či poskytuje naplněné modely dále vrstvě service (service neřeší jak a odkud se modely berou)
service: obsahuje business logiku (jako ověření práv uživatele, přidává informaci o jazykové mutaci) a poskytuje konkrétní funkcionalitu vrstvě view nebo pro api
view: zpracovává request, messages..., a je prošpikovaná mnoha try-except... a z logiky pouze volá svou funkci ve vrstvě service
template: zobrazí obdržená data od view v html šabloně

aby models.py tak nebobtnal, vytvářím ještě
forms: definuje jednotlivé formuláře a poskytuje naplněné modely (jako property)
fields: jednotlivé *field pro formuláře se svou validací

Dne neděle 2. září 2018 17:21:38 UTC+2 Honza Král napsal(a):

Honza Král

unread,
Sep 2, 2018, 1:23:13 PM9/2/18
to djan...@googlegroups.com


On Sun, Sep 2, 2018, 19:14 PavelZet <zeh...@gmail.com> wrote:
Django je založen na třívrstvém modelu MVC.
Tedy v modulech (aplikacích) defaultně vytváří vrstvy:
models (M) -> views (C) -> a přidáváme ještě templates (V)
V Django asi bývá zvykem všechnu logiku zahrnout do modelů a hotovo.

Ne, django neni MVC, nikdy nebylo. Porusuje ty principy ve spouste mistech.

Obecně při vývoji není dobré psát dlouhé špagetové soubory (soubor a třída do 200 řádků, funkce do 40 řádků), avšak pro větší moduly tyto tři vrstvy budou málo.
Já to řeším mj. dalšími vrstvami repository a service.
model -> repository -> service -> view -> template

Tajmestvi toho je, ze zadna z tech vrstev nemusi byt v jednom souboru, nic vas k tomu nenuti a muzete mit kod strukturovany (skoro) jak chcete.

model: definuje jen jak entity dat vypadají, jaké mají vztahy atp., prakticky obsahuje jen fields a meta
repository: zahrnuje veškerou logiku úložiště (jako režii s SQL, soubory, sítí, pamětí...) a ukládá či poskytuje naplněné modely dále vrstvě service (service neřeší jak a odkud se modely berou)
service: obsahuje business logiku (jako ověření práv uživatele, přidává informaci o jazykové mutaci) a poskytuje konkrétní funkcionalitu vrstvě view nebo pro api
view: zpracovává request, messages..., a je prošpikovaná mnoha try-except... a z logiky pouze volá svou funkci ve vrstvě service
template: zobrazí obdržená data od view v html šabloně

Tohle je popis jednoho arbitrarniho rozdeleni jak to delaji nektere produkty a frameworky, nikoli nejaka komplexni teorie, natoz dogma. Zkuste premyslet spis nad tim jak to ma django a jak se to dela v djangu nez se snazit namapovat jeden framework na druhy.

aby models.py tak nebobtnal, vytvářím ještě
forms: definuje jednotlivé formuláře a poskytuje naplněné modely (jako property)
fields: jednotlivé *field pro formuláře se svou validací

Forms a modely maji uplne jiny vyznam a duvod, neni jakkoliv mozne rict, ze vyvarim forms aby models nebobtnal.

PavelZet

unread,
Sep 3, 2018, 12:38:29 PM9/3/18
to django-cs


Dne neděle 2. září 2018 19:23:13 UTC+2 Honza Král napsal(a):


On Sun, Sep 2, 2018, 19:14 PavelZet <zeh...@gmail.com> wrote:
Django je založen na třívrstvém modelu MVC.
Tedy v modulech (aplikacích) defaultně vytváří vrstvy:
models (M) -> views (C) -> a přidáváme ještě templates (V)
V Django asi bývá zvykem všechnu logiku zahrnout do modelů a hotovo.

Ne, django neni MVC, nikdy nebylo. Porusuje ty principy ve spouste mistech.

To už je asi slovíčkaření, jestli dobře známé MVC, MTV nebo MVT. Principy jsou obdobné, šlo hlavně o zmínění třívrstvého modelu (který se obecně osvědčil).

Obecně při vývoji není dobré psát dlouhé špagetové soubory (soubor a třída do 200 řádků, funkce do 40 řádků), avšak pro větší moduly tyto tři vrstvy budou málo.
Já to řeším mj. dalšími vrstvami repository a service.
model -> repository -> service -> view -> template

Tajmestvi toho je, ze zadna z tech vrstev nemusi byt v jednom souboru, nic vas k tomu nenuti a muzete mit kod strukturovany (skoro) jak chcete.

Původně jsem chápal dlouhé špagetové soubory (models, views, ...) s mnoha kraťoučkými stereotypními funkcemi a třídami právě jako styl vývoje ražený Djangem.
Ale pokud to není "django-style", rozkládání jednotlivých tříd na soubory (jak se to dělá jinde) jen a jen uvítám.

Třeba models.py by měl sloužit jen jako výčet modelů a jednotlivé třídy modelů budou v jednotlivých souborech v podadresáři models (např. models/ProfileModel.py) ?
Nebo models.py vůbec není potřeba (pryč s ním) a místo něj stačí zmíněný podadresář models (se všemi modely po souborech) se souborem models/__init__.py (který původní models.py prakticky nahradí a ušetřím si psaní) ?

Je ale vhodné rozkládat na soubory i views.py, který neobsahuje třídy, ale jen funkce ?

Díky za reakci.


model: definuje jen jak entity dat vypadají, jaké mají vztahy atp., prakticky obsahuje jen fields a meta
repository: zahrnuje veškerou logiku úložiště (jako režii s SQL, soubory, sítí, pamětí...) a ukládá či poskytuje naplněné modely dále vrstvě service (service neřeší jak a odkud se modely berou)
service: obsahuje business logiku (jako ověření práv uživatele, přidává informaci o jazykové mutaci) a poskytuje konkrétní funkcionalitu vrstvě view nebo pro api
view: zpracovává request, messages..., a je prošpikovaná mnoha try-except... a z logiky pouze volá svou funkci ve vrstvě service
template: zobrazí obdržená data od view v html šabloně

Tohle je popis jednoho arbitrarniho rozdeleni jak to delaji nektere produkty a frameworky, nikoli nejaka komplexni teorie, natoz dogma. Zkuste premyslet spis nad tim jak to ma django a jak se to dela v djangu nez se snazit namapovat jeden framework na druhy.

A jak to dělá django :) ?
Model by tedy měl:
- definovat strukturu entity (popis tabulky)
- uchovávat obsah entity (konkrétní data entity)
- určovat vzhled na frontendu (propojení s widgety)
- dolovat data z úložiště (funkce čtení z databáze, sítě, paměti atd., tedy zastává funkci repozitáře)?

A business logiku bych měl uchovávat v nové vrstvě service nebo kde ? Do models ani views se mi nehodí :(
 

aby models.py tak nebobtnal, vytvářím ještě
forms: definuje jednotlivé formuláře a poskytuje naplněné modely (jako property)
fields: jednotlivé *field pro formuláře se svou validací

Forms a modely maji uplne jiny vyznam a duvod, neni jakkoliv mozne rict, ze vyvarim forms aby models nebobtnal.

Těch důvodů proč oddělit forms a fields je víc a docela se mi to osvědčilo.

Honza Král

unread,
Sep 3, 2018, 12:59:45 PM9/3/18
to djan...@googlegroups.com
tl;dr bavit se obecne o prazdnych (buzz)wordech jako "businees logika", "repozitar", nebo "mvc" proste nedava v tomhle kontextu smysl. Django nepouziva MVC, nepouziva repository pattern atd atd, snazit se pak o Djangu bavit v techto terminech je odsouzene k neuspechu protoze se snazite napasovat nepadnouci terminy na sebe a pak si stezujete, ze nepasujou.

On Mon, Sep 3, 2018 at 6:38 PM PavelZet <zeh...@gmail.com> wrote:


Dne neděle 2. září 2018 19:23:13 UTC+2 Honza Král napsal(a):


On Sun, Sep 2, 2018, 19:14 PavelZet <zeh...@gmail.com> wrote:
Django je založen na třívrstvém modelu MVC.
Tedy v modulech (aplikacích) defaultně vytváří vrstvy:
models (M) -> views (C) -> a přidáváme ještě templates (V)
V Django asi bývá zvykem všechnu logiku zahrnout do modelů a hotovo.

Ne, django neni MVC, nikdy nebylo. Porusuje ty principy ve spouste mistech.

To už je asi slovíčkaření, jestli dobře známé MVC, MTV nebo MVT. Principy jsou obdobné, šlo hlavně o zmínění třívrstvého modelu (který se obecně osvědčil).

ne, neni to slovickareni, pokud Django nedrzi ten trivrstvy model. Napriklad template tagy porusuji kompletne jakoukoliv izolaci mezi temi vrstvami, context processor anebo middleware take. Kdybychom chteli navic namapovat django komponenty na MVC tak by treba kontrolerum byl vice pribuzny urldispatcher nez view atp. Nemuzete rict, ze je to jen slovickareni protoze Django pouziva jina tri pismenka.


Obecně při vývoji není dobré psát dlouhé špagetové soubory (soubor a třída do 200 řádků, funkce do 40 řádků), avšak pro větší moduly tyto tři vrstvy budou málo.
Já to řeším mj. dalšími vrstvami repository a service.
model -> repository -> service -> view -> template

Tajmestvi toho je, ze zadna z tech vrstev nemusi byt v jednom souboru, nic vas k tomu nenuti a muzete mit kod strukturovany (skoro) jak chcete.

Původně jsem chápal dlouhé špagetové soubory (models, views, ...) s mnoha kraťoučkými stereotypními funkcemi a třídami právě jako styl vývoje ražený Djangem.
Ale pokud to není "django-style", rozkládání jednotlivých tříd na soubory (jak se to dělá jinde) jen a jen uvítám.

Třeba models.py by měl sloužit jen jako výčet modelů a jednotlivé třídy modelů budou v jednotlivých souborech v podadresáři models (např. models/ProfileModel.py) ?
Nebo models.py vůbec není potřeba (pryč s ním) a místo něj stačí zmíněný podadresář models (se všemi modely po souborech) se souborem models/__init__.py (který původní models.py prakticky nahradí a ušetřím si psaní) ?

Je ale vhodné rozkládat na soubory i views.py, který neobsahuje třídy, ale jen funkce ?

Díky za reakci.

kod je kod, neni na tom nic specifickeho, ze je pro django. Ano, kdyz jsou modely rozsahlejsi tak je casto rozhodim do vice souboru/modulu.
 


model: definuje jen jak entity dat vypadají, jaké mají vztahy atp., prakticky obsahuje jen fields a meta
repository: zahrnuje veškerou logiku úložiště (jako režii s SQL, soubory, sítí, pamětí...) a ukládá či poskytuje naplněné modely dále vrstvě service (service neřeší jak a odkud se modely berou)
service: obsahuje business logiku (jako ověření práv uživatele, přidává informaci o jazykové mutaci) a poskytuje konkrétní funkcionalitu vrstvě view nebo pro api
view: zpracovává request, messages..., a je prošpikovaná mnoha try-except... a z logiky pouze volá svou funkci ve vrstvě service
template: zobrazí obdržená data od view v html šabloně

Tohle je popis jednoho arbitrarniho rozdeleni jak to delaji nektere produkty a frameworky, nikoli nejaka komplexni teorie, natoz dogma. Zkuste premyslet spis nad tim jak to ma django a jak se to dela v djangu nez se snazit namapovat jeden framework na druhy.

A jak to dělá django :) ?

Django ma models ktere se staraji o databazi a vse kolem ni
url dispatcher ktery mapuje url na views
views ktere obstaravaji request/response cyklus

dale pak spousta optional nastroju ktere clovek muze a nemusi pouzit:
sablony ktere poskytuji nastroje na renderovani (nejen) html
formulare na ziskavani dat od uzivatele
middleware na globalni manipulaci request/response cyklu
management command na batch joby
...
...
...

Krome toho je uplne na vas, jak si veci rozdelite. Nektere business logika patri do modelu, nektere business logika ale nema vubec nic spolecneho s databazi a tak pravdepodobne patri do uplne samostatneho modulu (klidne uplne samostatne knihovny!). Nektera patri do formularu napriklad kdyz se tyka primarne ziskavani dat od uzivatelu.

Obecne nelze rict kam patri business logika protoze je to tak neuveritelne siroky pojem az postrada na vyznamu, zkuste dat nejake priklady.
 
Model by tedy měl:
- definovat strukturu entity (popis tabulky)
- uchovávat obsah entity (konkrétní data entity)
- určovat vzhled na frontendu (propojení s widgety)

ne, widgety nemaji s modelem nic spolecneho, to je otazka formularu. Ano, na modelu jsou nejake hooky aby se usnadnila tvorba formularu, ale to je jen zkratka.

- dolovat data z úložiště (funkce čtení z databáze, sítě, paměti atd., tedy zastává funkci repozitáře)?

repozitar je jeden z moznych patternu  na design ORM, django ho nepouziva, pouziva neco jineho. Nektere funkce ktere zastava tradicne repozitar jsou na modelech, nektere na querysetu atp, nema cenu se bavit o tom zda zastava funkci repozitare protoze repozitar neni funkce, je to jeden z mnoha moznych patternu co lide pouzivaji aby implementovali nejakou funkcionalitu. Ptejte se na tu funkcionalitu, ne zda se tohle reseni mapuje na jiny model reseni odjinud, to neni ani uzitecne ani mozne.


A business logiku bych měl uchovávat v nové vrstvě service nebo kde ? Do models ani views se mi nehodí :(

proc by se nehodila do models, respektive na manager, podle toho zda se tyka skupiny modelu nebo jen jedne instance? Nepiste, ze se vam to nehadi, napiste *proc*, jinak se o tom nemuzeme bavit.

 

aby models.py tak nebobtnal, vytvářím ještě
forms: definuje jednotlivé formuláře a poskytuje naplněné modely (jako property)
fields: jednotlivé *field pro formuláře se svou validací

Forms a modely maji uplne jiny vyznam a duvod, neni jakkoliv mozne rict, ze vyvarim forms aby models nebobtnal.

Těch důvodů proč oddělit forms a fields je víc a docela se mi to osvědčilo.

on hlavne neni jediny duvod proc je slucovat, nechapu proc je zminujete spolecne kdyz obe dve komponenty maji naprosto jiny ucel, semantiku a omezeni.
 
Reply all
Reply to author
Forward
0 new messages