Django: Wohin mit Model Update Code?

Django, Flask, Bottle, WSGI, CGI…
Antworten
brave
User
Beiträge: 24
Registriert: Mittwoch 24. Februar 2016, 18:30

Hallo Leute,

ich habe eine Frage zum Model Design beim Django Framework.

Worum gehts?
Jedesmal wenn der User einen "Update"-Button klickt, soll eine Routine(1) = scan ablaufen, welche einen Ordner auf einem Netzlaufwerk nach bestimmten Dateien (PDFs) scannt. Das Ergebnis dieser Routine(1) ist eine Liste Tuple-List aus (number, path, creationtime). Diese Routine(1) existiert bereits in einem eigenen Modul. Eine andere Routine(2) soll diese Liste nun mit der Datenbank abgleichen. Wenn der Eintrag schon existiert -> Ignore ansonsten Eintrag ergänzen.

Frage:
Die Frage ist wie oder eher wo genau implementiert man jetzt am besten Routine(2)?
Ich will irgendwie nicht meine ganzen views mit Model-Code vollpumpen. Schreibe ich einfach eine
eigene neue Klasse in models.py (z.B. Utils) rein und hole mir die dann in die views.py oder gibts da einen Django-Way?
Wie ist da die best practice?


models.py

Code: Alles auswählen

class Drawing(models.Model):
    number = models.CharField(max_length=11)
    path = models.CharField(max_length=256)
    creationdate = models.DateTimeField()

    # Dateiname ohne Pfad ausgeben lassen
    def __str__(self):
        return os.path.split(self.path)[1]

#Pseudo Code
class Utils:
    def update_db(project):
        updates = scan(project)
        for update in updates:
            check ob update in Drawing.objects.all()
                wenn ja: dann ignore,
                sonst: rein damit
        return success
views.py

Code: Alles auswählen

from .models import Utils as ut

def index(request):
    project = 'xyz'
    if ut.update_db(project):
        return HttpResponse("Update done.")
Btw.
Wie bekommt man hier denn so hübsch formatieren Code mit Highlighting rein?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

brave hat geschrieben:Ich will irgendwie nicht meine ganzen views mit Model-Code vollpumpen.
Da sich die Routine(1) bereits in einem eigenen Modul befindet, könntest Du die Routine(2) gleichfalls dort oder auch in einem eigenen Modul unterbringen. Der Pseudocode sähe dann so aus (Formatierung: Code selektieren und über der Textbox im Pulldown-Menü 'Code auswählen' Python auswählen):

Code: Alles auswählen

from modul1 import routine_1
from modul2 import routine_2

def update_view(request):
    ...
    result_1 = routine_1(request)
    result_2 = routine_2(result_1)
    ...
    return response 
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

2 ist ein Upsert und sollte im wesentlichen in der Datenbank passieren und gehört dementsprechend definitiv ins Model.
brave
User
Beiträge: 24
Registriert: Mittwoch 24. Februar 2016, 18:30

Ich habe jetzt den meisten Code in die models.py gepackt.

Was ich nach wie vor einfach nicht richtig verstehe, ist das import-System von Python. Wieso funktionieren relative imports manchmal und manchmal nicht? Hier ist meine Django Struktur: http://imgur.com/xkHmFwV

Wieso kann ich eine Klasse, die in models.py definiert ist in der views.py via from .models import Drawing importieren aber das gleiche Importstatement in bspw. in einem eigenen Modul easyscan.py nicht? Fehler: ImportError: cannot import name 'Drawing'

Ich brauche aber die Klasse "Drawing" in easyscan.py damit ich queryset-Methoden für den Zugriff auf die Datenbank ausführen kann. Was ist denn hier falsch? Überall ist eine __init.py__ und markiert den Ordner als Package/Subpackage und die Module werden per import eingebunden und nicht direkt ausgeführt.

ganz konkret:
Was genau muß ich machen, wenn ich Queryset Methoden (z.B. Drawings.objects.all() ) in einem anderen Modul als in models.py selbst oder in views.py benutzen will?
BlackJack

@brave: Da man relative Importe sowieso nicht verwenden sollte, erübrigt sich IMHO die Frage.

Um sie beantworten zu können reicht die Verzeichnisstruktur nicht aus. Was Dir nämlich auch noch Probleme bereiten könnte, sind zirkuläre Importe. Die sollte man auch nicht machen. Und eventuell noch andere Pfade/Module die im Suchpfad liegen.

Mach einfach überall absolute Importe.

Edit: Und mir scheinen da mindestens zwei `__init__.py`-Dateien zu viel zu sein, die da nicht hin gehören. Das könnte eventuell auch ein Grund sein.
brave
User
Beiträge: 24
Registriert: Mittwoch 24. Februar 2016, 18:30

Das package hat src als root. Von hier an liegt in jedem Unterordner genau eine __init__.py ohne Inhalt. Ein absolutes Import-Statement der Klasse Drawing aus models.py innerhalb von easyscan.py würde dann from src.apps.easyscan.models import Drawing. PyCharms autocomplete bietet das auch an, aber python meldet trotzdem einen ImportError.

Ich probier das am Wochenende nochmal in einem Testscenario aus. Ich hab jetzt erstmal den kompletten Code auf views.py und models.py aufgeteilt und das funktioniert ohne Probleme und ich kann erstmal weiterarbeiten.
BlackJack

@brave: Weder `src` noch `apps` sollten Packages sein.
Antworten