Search code examples
djangochoicefield

Request Clarification of Django Model Choice Code from Docs


In the official docs, https://docs.djangoproject.com/en/1.8/ref/models/fields/#choices we are given this example:

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)

What is the purpose of setting the variables to strings before, and in addition to, the actual tuples of YEAR_IN_SCHOOL_CHOICES? Where are those strings used? Are these variables then the same ones used in the tuple? If so, why? That seems like an additional and unnecessary step.

It does not help that in the example immediately before this one, they use different YEAR_IN_SCHOOL_CHOICES. Thanks for clarifying.

UPDATE

Since I am sitting here wrestling with this code as we speak, thanks to all for the quick responses. They all add something to my understanding. I think @shang-wang has the most concise and responsive answer to my question so far. 1+ for the reference to get_FOO_display(). But in my particular use case, the choices are for the admin to tell the end user how a particular object has been evaluated. So I want the 'human-readable' form of the evaluations to be what displays in the final html template to the end user on the site. In light of these answers, now I'm wondering if this is the best way to achieve my goal? Is the solution :

`

html display table

Name of object | Evaluation

FOO | foo.get_evaluation_display()

or maybe:

for FOO in objects:
Name of object | Evaluation
FOO.name | foo.get_evaluation_display()
'

The purpose of this particular model is to display expert evaluations of FOO to end users. Each FOO can have many such evaluations. Although usually quite verbose, these evaluations can be categorized, hence the choice field. Users can then click over to read the original evaluation in full if they want. So FOO is defined on a different model, and is linked to the evaluation model by a foreign key. So will get_FOO_display() actually work here, since the choice field isn't on the model where FOO is an instance?

p.s, I realize this has now become a different question, so if it needs to be moved or whatever, I'm ok with that, but it does come directly from the original q&a. Let me know. Thx.


Solution

  • The variable YEAR_IN_SCHOOL_CHOICES is served as all possible choices in the field year_in_school. The first value in each pair in YEAR_IN_SCHOOL_CHOICES is the one that will be stored in database, while the second value in each pair is the one that will show up in your form dropdown(if you use the default widget). The individual selection declaration like FRESHMAN = 'FR' is to make sure that they are encapsulated in the class. You can do the following for each student object:

    # assign the value to student's year_in_school
    student.year_in_school = Student.FRESHMAN
    student.save()
    
    # this will print 'FR'
    db_value = student.year_in_school
    print db_value
    
    # this will print 'Freshman'
    pretty_display_value = student.get_year_in_school_display()
    print pretty_display_value
    

    Django doc for get_FOO_display.