Introduction
This is an article where the main focus is also about how to solve a specific error message. The error occurs when executing a specific part of source code using Django-based application. That part exist in the initialization of a form property. That form property part has a specific purpose to render the dropdown list element. It is also exist in the previous article. That article has the title of ‘How to Solve Error Message TypeError: ‘ModelBase’ object is not subscriptable when Running Django Application’. It exist in this link. The following is the error message appear in the log output of the Django application internal server running :
File "C:\project\apps\apps\urls.py", line 2, in <module> from .views import * File "C:\project\apps\apps\views.py", line 23, in <module> from apps.org import views File "C:\project\apps\apps\views.py", line 9, in <module> from .forms import OrganizationActivityForm File "C:\project\apps\apps\org\forms.py", line 14, in <module> class OrganizationNewForm(forms.ModelForm): File "C:\project\apps\apps\org\forms.py", line 15, in OrganisasiNewForm program = forms.CharField(label = 'Program', widget = forms.Select(choices=Organization.program)) File "C:\project\winenv\lib\site-packages\django\forms\widgets.py", line 565, in __init__ self.choices = list(choices) TypeError: 'DeferredAttribute' object is not iterable
Before going on to the solution, the following is the content of the models.py file describing the models :
class Activity(models.Model): id = models.AutoField(primary_key=True) code = models.CharField(max_length=10, blank=True, null=True) name = models.TextField() class Meta: verbose_name_plural = "Activities" def __str__(self): # return self.name return '%s %s' %(self.code, self.name) class Organization(models.Model): unit = models.CharField(db_column='unit', max_length=100) program = models.TextField(blank=True, null=True,) activity = models.ForeignKey('Activity', blank=True, null=True, on_delete=models.CASCADE) is_aktif = models.BooleanField() def __str__(self): return self.unit def save(self, *args, **kwargs): return super().save(*args, **kwargs) class Meta: verbose_name_plural = 'Organizations' db_table = 'apps_organization' def __unicode__(self): return self.unit
Furthermore, the following is the script with the name ‘forms.py’ file with the following content :
class OrganizationNewForm(forms.ModelForm): program = forms.CharField(label = 'Program', widget = forms.Select(choices=Organization.program)) activity = forms.CharField(label = 'Activity', widget = forms.Select(choices=Activity.name)) class Meta: model = Organization fields = ('unit',)
Actually, it is at that part in the ‘forms.py’ file where the declaration of filling the dropdown list from a model exist causing the error message :
program = forms.CharField(label = 'Program', widget = forms.Select(choices=Organization.program))
Solution
So, as for the solution on the error message, it is actually the same solution in the previous article. Just change how to define or initialize the dropdown list element of the form. Although the error is very different which exist as follows :
TypeError: 'DeferredAttribute' object is not iterable
Basically, the wrong declaration for dropdown list initialization which is different causing different errors. In other words, the solution is just to change the ‘forms.py’ file which in the declaration part of the dropdown list. The following is the modification of it :
program = forms.ModelChoiceField(queryset = Organization.objects.all(), initial = 0)
By modifying the source with the above pattern, the following is the forms.py modification in order to define dropdown list initialization :
class OrganizationNewForm(forms.ModelForm): program = forms.ModelChoiceField(queryset = Organization.objects.all(), initial = 0) activity = forms.ModelChoiceField(queryset = Activity.objects.all(), initial = 0) class Meta: model = Organization fields = ('unit',)
Finally, the Django template file for rendering the dropdown list is exist as in the following content :
<form method="post"id="activityForm" action="{% url 'org_activity_save' %}"> {% csrf_token %} {{ form.as_table }} <button type="submit">Submit</button> </form>