[Django] choice daten anders festhalten als in einem Tuple..

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Es lohnt sich ja nicht immer für ein kleine Auswahl (für ein choice Feld) eine eigene Modell-Klasse zu machen. Erst recht dann nicht, wenn es sich quasi um Konstanten handelt.

Man kann choices ja in einem Tuple stopfen und in forms oder models nutzten, beispiele findet man hier: http://docs.djangoproject.com/en/dev/re ... s/#choices

Was ich meine ist sowas:

Code: Alles auswählen

TYPE_CHOICES = (
  (0, "wiki page"),
  (1, "cms page"),
  (2, "blog entry"),
  (3, "static file"),
)
Aber irgendwie ist das dumm. Früher oder später wird man im Code eine Verknüpfung der ID mit dem Text haben wollen. Also muß man garantieren, das die ID überall das selbe meint. Nun könnte man das machen:

Code: Alles auswählen

TYPE_WIKI = 0
TYPE_CMS = 1
TYPE_BLOG = 2
TYPE_FILE = 3

TYPE_CHOICES = (
  (TYPE_WIKI, "wiki page"),
  (TYPE_CMS, "cms page"),
  (TYPE_BLOG, "blog entry"),
  (TYPE_FILE, "static file"),
)
Nun kann man die "Konstanten" in andere Module importieren und damit arbeiten. Ist aber alles ein wenig viel Tipparbeit... Aber, wenn eine ID ändert, dann muß man keine anderen Code Teile ändern. Außerdem sieht man überall im Code, das hinter eine ID steckt, weil man ja nicht die Zahl nimmt, sondern die Variable...

Eine andere Variante wäre das:

Code: Alles auswählen

TYPE_CHOICES = (
  ("wiki", "wiki page"),
  ("cms", "cms page"),
  ("blog", "blog entry"),
  ("file", "static file"),
)
Ist aber auch nicht so richtig schön, weil man nun z.B. in einem Modell nicht mehr ein einfaches Integer Feld nehmen kann... Auf der anderen Seite kann man sogar direkt in der Datenbank sehen um was für ein Typ es sich handelt.
OK, man könnte auch nur immer ein oder zwei Buchstaben nehmen, statt dem ganzen Wort, aber dann ist das auch nicht mehr ganz so eindeutig...

Es gibt auch situationen wo hinter diesem Typ auch z.B. verschiedene methoden einer klasse oder Funktionen stehen. Dann wäre es nett, wenn man sowas einfacher machen könnte:

Code: Alles auswählen

if item == 0:
    call_wiki(foo, bar)
elif item == 1:
    call_cms(foo, bar)
...
else:
    raise Error...
Ich überlege ob es nicht Sinn macht, irgendein Objekt sich zu bauen, was die Verwaltung einfacher machen könnte... Hat jemand sowas schon gemacht? Oder wie macht ihr das???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Google hilft, james bennet hat auch schon darüber geschrieben, in den Kommentaren steht dann einiges über eigene Objects...
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Du meinst wohl das hier: http://www.b-list.org/weblog/2007/nov/0 ... right-way/

Es gibt noch ein paar Ansätze hier: http://www.djangosnippets.org/tags/choices/ (da sind allerdings viele nicht sehr überzeugend)

Das mit den Konstanten scheint mir noch der beste Weg zu sein, hat Bennett ja auch im Programm:

Code: Alles auswählen

class Entry(models.Model):
    LIVE_STATUS = 1
    DRAFT_STATUS = 2
    HIDDEN_STATUS = 3
    STATUS_CHOICES = (
        (LIVE_STATUS, 'Live'),
        (DRAFT_STATUS, 'Draft'),
        (HIDDEN_STATUS, 'Hidden'),
    )
    # ...some other fields here...
    status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Jagut, man könnte das auch als Klasse machen. Und dann eben einen List-"Parser" einbauen, für Django.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach, früher oder später wir man bestimmt mal im view die Bezeichnung anhand der ID haben wollen... Für den Fall kann man auch gleich noch ein dict mit den Daten ablegen, z.B.:

Code: Alles auswählen

class Entry(models.Model):
    LIVE_STATUS = 1
    DRAFT_STATUS = 2
    HIDDEN_STATUS = 3

    STATUS_CHOICES = (
        (LIVE_STATUS, 'Live'),
        (DRAFT_STATUS, 'Draft'),
        (HIDDEN_STATUS, 'Hidden'),
    )
    STATUS_DICT = dict(STATUS_CHOICES)

    # ...some other fields here...
    status = models.IntegerField(choices=STATUS_CHOICES, default=LIVE_STATUS
Dann kann man mit Entry.STATUS_DICT[current_status] an den Namen kommen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten