Reputation:
I have three models bound together by foreign keys: Course > Lecture > FileUpload. I tried to create a form for Lecture model, but I actually ended up creating two forms, another one for FileUpload. And every time I try to submit the forms, I get error:
Exception Type: IntegrityError at /courses/teacher/classroom/
Exception Value: (1048, "Column 'lecture_id' cannot be null")
The Lecture form actually submits the information, and I think that the error is related to the second form. Thing is that I want the user to be able to upload many files for the same lecture, just like in the database, and currently only one file could be uploaded which is not working.
View:
def classroom(request):
if request.method == 'POST':
form1 = LectureForm(request.POST)
form2 = FileForm(request.POST, request.FILES)
if form1.is_valid() and form2.is_valid():
form1.save()
form2.save()
return redirect('courses/courses.html')
else:
form1 = LectureForm()
form2 = FileForm()
context = {'teacher_data': TeacherData.objects.all(),
'teachers': Teacher.objects.all(),
'courses': Course.objects.all(),
'form1': form1,
'form2': form2,
}
return render(request, 'courses/classroom.html', context)
Forms:
class LectureForm(forms.ModelForm):
class Meta:
model = Lecture
fields = ('course', 'lecture_title', 'lecture_category', 'content')
class FileForm(forms.ModelForm):
class Meta:
model = FileUpload
fields = ('files',)
Models:
class Course(models.Model):
name = models.CharField(max_length=50, unique=True)
class Lecture(models.Model):
LECTURE_CHOICES = (
('Courses', 'Courses'),
('Seminars', 'Seminars'),
)
course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures',)
lecture_category = models.CharField(max_length=10, choices=LECTURE_CHOICES, default='Courses',)
lecture_title = models.CharField(max_length=100, blank=True, null=True)
content = models.TextField(blank=True, null=True)
class FileUpload(models.Model):
files = models.FileField(upload_to='documents', null=True, blank=True)
lecture = models.ForeignKey('Lecture', related_name='files', on_delete=None, default=None)
Traceback: https://pastebin.com/5ViFarGP
Upvotes: 0
Views: 618
Reputation: 47364
To fix the error you need to pass lecture
object to file
before saving it to DB:
if form1.is_valid() and form2.is_valid():
lecture = form1.save()
file = form2.save(commit=False)
file.lecture = lecture
file.save()
To create multiple related object at the same time you can use formsets
. In your case you need to do something like this:
from django.forms.models import inlineformset_factory
FileFormset = inlineformset_factory(Lecture, FileUpload, fields=('files',))
if request.method == 'POST':
form1 = LectureForm(request.POST)
if form1.is_valid():
lecture = form1.save()
formset = FileFormset(request.POST, request.FILES, instance=lecture)
if formset.is_valid():
formset.save()
return redirect('courses/courses.html')
else:
form1 = LectureForm()
formset = FileFormset()
context = {'teacher_data': TeacherData.objects.all(),
'teachers': Teacher.objects.all(),
'courses': Course.objects.all(),
'form1': form1,
'formset': formset,
}
In template add inside <form>
tag:
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
Upvotes: 1