Display option value and text to select

Question:

I have a select field populated from the database table ‘Grade’. It displays Grade objects instead of ‘Grade 1’, ‘Grade 2’, ‘Grade 3’ etc. How can I populate the select to display the texts.
Current Output

My codes:

models.py

class Grade(models.Model):
    grade_id = models.AutoField(primary_key=True)
    grade_name = models.CharField(max_length=10, default="")
    class Meta:
        db_table = 'grade'


class Student(models.Model):
    student_id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=50, default="")
    last_name = models.CharField(max_length=50, default="")
    grade = models.ForeignKey(Grade, on_delete=models.CASCADE)
    class Meta:
        db_table = 'Student'

forms.py

class CreateStudentForm(forms.ModelForm):
    class Meta:
        model = Student
        fields = ['grade', 'first_name', 'last_name' ]
        widgets = {
            'grade': forms.Select(choices=Grade.objects.all(), attrs={'id':'selectGrade', 'class': 'form-control'}),
            'first_name': forms.TextInput(attrs={'id':'txtFirstName', 'class': 'form-control', 'placeholder': 'First Name'}),
            'last_name': forms.TextInput(attrs={'id':'txtLastName', 'class': 'form-control', 'placeholder': 'Last Name'}),
        }

views.py

def student_action(request):
    form = CreateStudentForm()
    return render(request, 'student.html', {'form': form})
Asked By: Lucius Ferdinand

||

Answers:

You need to write str method for represent grade_name instead of Object name like this …

models.py

class Grade(models.Model):
    grade_id = models.AutoField(primary_key=True)
    grade_name = models.CharField(max_length=10, default="")
    class Meta:
        db_table = 'grade'
    
    def __str__(self):
        return self.grade_name

You should define the __str__() method in the model so:

class Grade(models.Model):
    grade_id = models.AutoField(primary_key=True)
    grade_name = models.CharField(max_length=10, default="")

    def __str__(self):
        return f"{self.grade_name}"

    class Meta:
        db_table = 'grade'

How to display Select Grade instead of – – – – – –?

You can override the __init__() method of ModelForm so:

class CreateStudentForm(forms.ModelForm):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['grade'].empty_label = 'Select Grade'
    
    class Meta:
        model = Student
        fields = ['grade', 'first_name', 'last_name' ]
        widgets = {
            'grade': forms.Select(choices=Grade.objects.all(), attrs={'id':'selectGrade', 'class': 'form-control'}),
            'first_name': forms.TextInput(attrs={'id':'txtFirstName', 'class': 'form-control', 'placeholder': 'First Name'}),
            'last_name': forms.TextInput(attrs={'id':'txtLastName', 'class': 'form-control', 'placeholder': 'Last Name'}),
        }    
Answered By: Sunderam Dubey