Django - Choices is not defined - Warum zweimal verschachteln?

Django, Flask, Bottle, WSGI, CGI…
Antworten
SnakeBite
User
Beiträge: 46
Registriert: Mittwoch 4. März 2009, 18:26

Hallo.

Ich hab mir gerade die offizielle Django Doku genauer angesehen und bin dabei auf folgendes Beispiel für Choices gestoßen:

Code: Alles auswählen

class Student(models.Model):
    FRESHMAN = 'FR'
    SOPHOMORE = 'SO'
    JUNIOR = 'JR'
    SENIOR = 'SR'
    YEAR_IN_SCHOOL_CHOICES = (
        (FRESHMAN, 'Freshman'),
        (SOPHOMORE, 'Sophomore'),
        (JUNIOR, 'Junior'),
        (SENIOR, 'Senior'),
    )
    year_in_school = models.CharField(max_length=2,
                                      choices=YEAR_IN_SCHOOL_CHOICES,
                                      default=FRESHMAN)
An sich nicht so schwierig, aber wieso muss man erst "FRESHMAN = 'FR'" definieren? Wenn ich direkt

Code: Alles auswählen

 YEAR_IN_SCHOOL_CHOICES = (
        ('FR', 'Freshman'),
eintippe, heisst es nur FR is not defined.

Warum diese unnütze extra Verschachtelung? Ist das eine Python oder Django Sache? Dann hab ich zwei verschiedene Definitionen (FRESHMAN und FR) für eine Sache. Finde ich unnötig verwirrend.

Vielen Dank schonmal!
BlackJack

@SnakeBite: Das glaube ich jetzt mal nicht. Kannst Du ein komplettes Beispiel zeigen mit dem dazugehörigen Traceback?

Ansonsten ist das ja schon deswegen nicht unnütz weil man im Quelltext ja doch ganz gerne `Student.FRESHMAN` stehen haben möchte statt 'FR', was total nichtssagend ist und auch Freitag bedeuten könnte.
SnakeBite
User
Beiträge: 46
Registriert: Mittwoch 4. März 2009, 18:26

Ich hab mich auch gewundert.

Das hier ist meine models.py:

Code: Alles auswählen

class Video(models.Model):
	LANGUAGE_CHOICES = (
		(EN, "English"),
	)
	language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES, default=EN)
Und das hier ist meine "makemigrations" traceback:

Code: Alles auswählen

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "...Django/lib/python3.5/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "...Django/lib/python3.5/site-packages/django/core/management/__init__.py", line 327, in execute
    django.setup()
  File "...Django/lib/python3.5/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "...Django/lib/python3.5/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "...Django/lib/python3.5/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "...Django/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 662, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "...models.py", line 5, in <module>
    class Video(models.Model):
  File "...models.py", line 9, in Video
    language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES, default=EN)
NameError: name 'EN' is not defined
Es passiert unabhängig davon ob ich <EN> oder <"EN"> nehme
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Der Fehler hat mit Django nichts zu tun und sollte bei dem Quelltext schon früher auftauchen, es sei den du nutzt konsequent "EN", dann kann der Fehler nämlich garantiert nicht auftauchen.

Poste mal den Code den du auch tatsächlich ausführst.
BlackJack

@SnakeBite: Naja, das ist bei dem gezeigten Quelltext klar, das hat nichts mit Django zu tun. Jetzt mal bitte einen Quelltext bei dem Du denkst das Django ”schuld” ist.
SnakeBite
User
Beiträge: 46
Registriert: Mittwoch 4. März 2009, 18:26

Hmm jetzt sitz ich auf der Leitung. Das ist doch der ganze Quelltext. Wollte nur testen wie das mit den choices funktioniert. Was ist denn falsch? Der models code hat auch keine Vertipper. Ist "EN" sowas wie ne geschützte "Standard-Variable vielleicht?
BlackJack

@SnakeBite: Das ist Quelltext bei dem klar ist, dass der die Ausnahme auslösen wird. Ganz einfach weil `EN` benutzt wird ohne es zu definieren. Und das hat rein gar nichts mit Django zu tun. Deine Frage war ja aber warum Django Dich zu etwas zwingt. Und *dafür* hast Du noch kein Beispiel gezeigt.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@SnakeBite: das du sowas wie

Code: Alles auswählen

my_choices= ('foo', 'the foo text'),
    ('spam', 'the spam text'),)
angeben musst hat weder was mit Python noch mit Django zu tun, sondern mit dem HTML SELECT-Feld, was darauf vielleicht / wahrscheinlich mal generiert wird. `foo` oder `spam`sind die Werte, die auch mal in der DB gespeichert werden, `the foo text` und `the spam text`ist das, was im Auswahlfeld als Text angezeigt wird. Siehe auch: https://developer.mozilla.org/en-US/doc ... ent/select

Dein Fehler ist, dass du in den Tuplen keine Strings angibst, so wie im Django Tutorial Beispiel und im Beispiel oben.

Übrigens funktioniert das bei allen anderen Frameworks auch so. Wenn du z.B. mal in die Doku von WTforms schaust, wirst du ähnliche Beispiele finden.

Gruß, noisefloor
SnakeBite
User
Beiträge: 46
Registriert: Mittwoch 4. März 2009, 18:26

Ahhhh OK.
Also das mit den Strings hab ich gestern Abend selbst noch bemerkt. Das ist jetzt klar. Aber die eigentliche Frage war tatsächlich wieso ich

Code: Alles auswählen

("EN", "English"), ("DE", "German"), etc...
machen muss, anstatt einfach:

Code: Alles auswählen

LANG_CHOICES = ["English", "German", etc...]
Die Erklärung mit den Select fields macht Sinn, wäre ich aber selbst nie drauf gekommen.

So viel "Kleinzeugs" das man wissen muss, um wirklich auch zu verstehen was man "da eigentlich genau macht". Das ist manchmal echt frustrierend. Aber zumindest diese Kleinigkeit hätte ich jetzt gelernt.

Vielen Dank!
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du musst auch Bedenken dass man die Labels auch übersetzen oder auch verändern können möchte. Das geht schlecht wenn die gleichzeitig die Werte sind mit denen man im Code arbeitet und in die Datenbank schreibt.
Antworten