ModelChoiceFIeld Usage and what to include in queryset?

I cannot seem to figure out why my ModelChoiceField is not working, even after going through the django documentation about ModelForm which confused me despite having successfully relied on them throughout my learning. The error in my code is probably silly, and I apologize for that in advance.

The error I get on my terminal when trying to makemigrations is:

'line 429, in getattr raise AttributeError(name) from None AttributeError: objects'

forms.py

from random import choices
from django import forms
from .models import Student
from students.choices import *

class StudentForm(forms.ModelForm):
    class Meta:
        model = Student
        fields = '__all__'      #imports all of Student model's fields
        labels = {
            'student_number': 'Student Number',    #changes how the attribute names are presented to the user
            'first_name': 'First Name',
            'last_name': 'Last Name',                       
            'email': 'Email',
            'english': 'English',
            'math': 'Math',
            'language': 'Language',
            'science': 'Science',
            'ib_predicted': 'Predicted IB Score'
        }
        widgets = {
            'student_number': forms.NumberInput(attrs={'class': 'form-control'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control'}),                     
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'english': forms.ModelChoiceField(queryset=English.choices),
            'science': forms.ModelChoiceField(queryset=Science.objects.all()),
            'language': forms.ModelChoiceField(queryset=Language.objects.all()),
            'math': forms.ModelChoiceField(queryset=Math.objects.all()),
            'ib_predicted': forms.NumberInput(attrs={'class': 'form-control'})
        }

choices.py

from unittest.util import _MAX_LENGTH
from django.db import models
from django.utils.translation import gettext_lazy as _


class English(models.TextChoices):
    LANGLIT = 'LL', _('Language and literature')
    LIT = 'L', _('Literature')
    

class Math(models.TextChoices):
    AA = 'AA', _('Analysis & Approaches')
    AI = 'AI', _('Analysis & Interpretation')


class Language(models.TextChoices):
    FRENCH = 'F', _('French')
    SPANISH = 'S', _('Spanish')
    ARABIC = 'A', _('Arabic')
    MANDARIN = 'M', _('Mandarin')


class Science(models.TextChoices):
    BIOLOGY = 'BIO', _('Biology')
    CHEMISTRY = 'CHEM', _('Chemistry')
    PHYSICS = 'PHY', _('Physics')
    COMPUTERSCIENCE = 'CS', _('Computer Science')
    DESIGNTECHNOLOGY = 'DT', _('Design Technology')
    ESS = 'ESS', _('Environmental Systems and Societies')


class Society(models.TextChoices):
    MANAGEMENT = 'BM', _('Business Management')
    ECONOMICS = 'ECON', _('Economics')
    GEOGRAPHY = 'GEO', _('Geography')
    GLOBALPOLITICS = 'GP', _('Global Politics')
    HISTORY = 'HIS', _('History')
    PSYCHOLOGY = 'PSYCH', _('Psychology')

class Art(models.TextChoices):
    VISUALARTS = 'VA', _('Visual Arts')
    MUSIC = 'MUS', _('Music'),
    FILM = 'FILM', _('Film')


models.py

from unittest.util import _MAX_LENGTH
from django.db import models
from django.utils.translation import gettext_lazy as _
from students.choices import *

# Create your models here.


class Student(models.Model):
    student_number = models.PositiveIntegerField()
    first_name = models.CharField(max_length=50) #Attribute containing student's first name, cannot exceed 50 characters
    last_name = models.CharField(max_length=50) #Attribute containing student's last name, cannot exceed 50 characters
    email = models.EmailField(max_length=100) #Attribute containing student's email, cannot exceed 100 characters
    ib_predicted = models.IntegerField()
    
    #Subjects
    english = models.CharField(max_length=2, choices=English.choices)
    math = models.CharField(max_length=2, choices=Math.choices)
    language = models.CharField(max_length=1, choices=Language.choices)
    science = models.CharField(max_length=4, choices=Science.choices)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

You should use forms.ChoiceField and not forms.ModelChoiceField.

ModelChoiceField is used when you want to choose among ForeignKeys or database Models.

Initialise your choices with forms.ChoiceField(choices=Math.choices)

Reference: https://docs.djangoproject.com/en/4.1/ref/forms/fields/#choicefield

Back to Top