I try create comments form add and take error. But I'm not shure that I correctly use lesson = at view.py at def post function. Can You help me?
models.py:
class Comment(models.Model):
text = models.TextField('Comment text')
user = models.ForeignKey(User, on_delete=models.CASCADE)
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
view.py:
class LessonDetailPage(DetailView):
....
def post(self, request, *args, **kwargs):
lesson = Lesson.objects.filter(slug=self.kwargs['lesson_slug']).first()
post = request.POST.copy()
post['user'] = request.user
post['lesson'] = lesson
request.POST = post
form = CommentForms(request.POST)
if form.is_valid():
form.save()
part of urls.py
path('course/<slug>/<lesson_slug>', views.LessonDetailPage.as_view(), name='lesson-detail'),
forms.py:
class CommentForms(forms.ModelForm):
text = forms.CharField(
label='Text',
required=True,
widget=forms.Textarea(attrs={'class': 'form-control'})
)
user = forms.CharField(
widget=forms.HiddenInput()
)
lesson = forms.CharField(
widget=forms.HiddenInput()
)
class Meta:
model = Comment
fields = ['text']
comment.html
<div >
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">ОК</button>
</div>
And my Error
IntegrityError at /course/linux/set-on-linux
NOT NULL constraint failed: courses_comment.lesson_id
Request Method: POST
Request URL: http://127.0.0.1:8000/course/linux/set-on-linux
Django Version: 4.0.6
Exception Type: IntegrityError
Exception Value:
NOT NULL constraint failed: courses_comment.lesson_id
CodePudding user response:
My suspicion is that this is causing your issue:
lesson = Lesson.objects.filter(slug=self.kwargs['lesson_slug']).first()
What this is doing is returning the first Lesson object in a queryset filtered by your lesson slug. However, filter will return an empty queryset if there are no results. Running first()
on that empty queryset will return nothing, which would explain why an ID is not being passed to your form.
To solve this, you just need to catch whether the lesson
object is empty:
if lesson is None:
# do something else
As an aside, combining .filter()
and .first()
is generally not recommended as you are potentially being vague with your object selection. Using .get()
will get you a single object and return an error if two or more are returned. The downside with .get()
is that it will also raise an exception if nothing is returned, so you need to handle both outcomes in your view.
CodePudding user response:
May be not best solution but It's work:
def post(self, request, *args, **kwargs):
lesson = Lesson.objects.filter(slug=self.kwargs['lesson_slug']).first()
post = request.POST.copy()
post['user'] = request.user
post['lesson'] = lesson
request.POST = post
form = CommentForms(request.POST)
if form.is_valid():
comment = Comment(text=request.POST['text'], user=request.POST['user'], lesson=request.POST['lesson'])
comment.save()