I think I have a fundamental misunderstanding of using the ORM in Django with ModelForms and, although I’ve been pouring through search engines since mid-day Friday, I feel I am no further on in figuring this out.
I have two models as shown here…
class Modules(models.Model):
module_code = models.CharField(max_length=5)
module_name = models.CharField(max_length=100)
datetimestamp = models.DateTimeField(auto_now=True)
class Meta:
# Defines the name to appear in the Admin section
verbose_name_plural = "Modules"
class ChangeLogEntries(models.Model):
change_date = models.DateField()
change_note = models.TextField()
form_name = models.CharField(max_length=100)
datetimestamp = models.DateTimeField(auto_now=True)
module_code = models.CharField(max_length=5, null=True)
binary_only = models.BooleanField(default=False)
installed = models.BooleanField(default=False)
dateinstalled = models.DateField(blank=True, null=True)
module_category = models.ForeignKey(Modules, default=1, verbose_name="Module",
on_delete=models.SET_DEFAULT, null=True)
class Meta:
# Defines the name to appear in the Admin section
verbose_name_plural = "Log Entries"
def __str__(self):
return self.module_code
I have a form which will be used to create a new ChangeLogEntries row as shown here…
class CreateLogEntryForm(forms.ModelForm):
class Meta:
model = ChangeLogEntries
fields = ['change_date', 'change_note', 'module_code', 'binary_only', 'form_name']
def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)
today = date.today()
self.fields['change_date'] = forms.DateField(initial=today, required=True,
widget=DateInput(attrs={'type': 'date', 'style': 'width:200px'}))
self.fields['change_note'].widget = Textarea(attrs={'rows': '6', 'cols': '80'})
module_categories = Modules.objects.all().order_by('module_name').values_list('id', 'module_name')
self.fields['module_category'] = forms.CharField(label="Module Name", required=True,
widget=forms.Select(choices=module_categories,
attrs={'style': 'width: 300px;'}))
self.fields['form_name'] = forms.CharField(label="Form/Class Name", required=False, initial="", max_length=50)
def clean(self):
super(CreateLogEntryForm, self).clean()
# get the change note from the data
change_note = self.cleaned_data.get('change_note')
if len(change_note) < 5:
self.errors['change_note'] = self.error_class(['The change note requires a minimum of 5 characters.'])
# the form name must have at least 5 characters in order to be valid
form_name = self.cleaned_data.get('form_name')
if len(form_name) > 0:
if len(form_name) < 5:
self.errors['form_name'] = self.error_class(
['The form name if specified, must be at least 5 characters.'])
# if the binary-only field is checked, then we should not have a form name
binary_only = self.cleaned_data.get('binary_only')
if binary_only:
self.errors['binary_only'] = self.error_class(
['If Binary-Only is checked, you should not specify a form name.'])
return self.cleaned_data
Here is the code views.py…
def createlogentry(request):
if request.method == 'POST':
form = CreateLogEntryForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
return render(request, 'main/createlogentry.html', {'form': form})
else:
form = CreateLogEntryForm()
return render(request,
'main/createlogentry.html',
{'form': form
})
The template correctly shows the module list for selection, but when I attempt to save, I get a validation error that the field is required, which I believe is referring to the module_category.
I’m thinking that the dropdown list for Select Module is not correctly defined in the form and that I should be, somehow displaying objects directly from the Modules model. However, I’m not sure how to do that. I haven’t even gotten to the point in views.py where I try to save this, but maybe, just getting the form definition correct will solve the issue.
At this point, I’m trying to find some example that is similar to what I am trying to do here, namely, save a log entry with a valid, related entry from the Modules model. If you can point me in that direction, or provide some feedback here, I would greatly appreciate it. Also, let me know if there is any other information that would be helpful to post.