Home > Software engineering >  IntegrityError at /answer/ NOT NULL constraint failed: answer_answer.post_id
IntegrityError at /answer/ NOT NULL constraint failed: answer_answer.post_id

Time:05-17

I have 2 models one for Question and one for Answer when i submitted answer form its throws me an error like this: IntegrityError at /answer/ NOT NULL constraint failed: answer_answer.post_id I'm trying to fix it by adding blank=False and null=False and deleted my migrations but still the error is there. How can I solve this problem please.

I want a user to be able to post an answer to a single question the error comes from my My_Answer view and it's highlight this line of code:

return super (My_Answer,self).form_valid(form)

my models

class Question(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100, blank=False, null=False)
    body = RichTextField(blank=False, null=False) 
    category = models.CharField(max_length=50, blank=False, null=False)

    def __str__(self):
        return str(self.user)

class Answer(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    answer = RichTextField(blank=False, null=False)
    post = models.ForeignKey(Question, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.user)

the views

def viewQuestion(request, pk):
    question = Question.objects.get(id=pk)
    answers = Answer.objects.filter(post_id=question)
    context = {'question':question, 'answers':answers}
    return render(request, 'viewQuestion.html', context)


class My_Question(LoginRequiredMixin, CreateView):
     model = Question
     fields = ['title', 'body', 'category']
     template_name = 'question.html'
     success_url = reverse_lazy('index')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super (My_Question, self).form_valid(form)

class My_Answer(LoginRequiredMixin, CreateView):
    model = Answer
    fields = ['answer']
    template_name = 'answer.html'
    success_url = reverse_lazy('index')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super (My_Answer, self).form_valid(form)

the viewQuestion template:

<div >
    <div >
        <h1>{{question.title}}</h1>
        <hr>
    </div>
    <br>
    <h3 style="font-family: arial;">{{question.body|safe}}</h3>
    <hr>
    <br>
    <h5>{{question.user.username.upper}}</h5>
</div>
<!--question-->
<div >
    <div >
        <a href="{% url 'answer' %}" >Post Your Answer</a>
    </div>
</div>
<br>
<br>
<!--answer-->
<div >
    {% for answer in answers reversed %}
    <div >
        <p>{{answer.user}}</p>
        <p>{{answer.answer|safe}}</p>
    </div>
    {% endfor %}
</div>

Thank you for your help.

CodePudding user response:

You are saving an answer instance with only answer from form and user from request user but where is a post id which cannot be none and is required.

you url patterns should look like this

urlpatterns = [
    path('question/<int:pk>/', viewQuestion, name='view-question'),
    path('question/<int:pk>/answer/', My_Answer.as_view(), name='answer'),
]

You only have to change url in viewQuestion.html as

<div >
    <a href="{% url 'answer' pk=question.pk %}" >Post Your Answer</a>
</div>

And in answer views as

def form_valid(self, form):
    form.instance.user = self.request.user
    form.instance.post_id = self.kwargs['pk']
    return super (My_Answer, self).form_valid(form)

So basically you are saving answer instance without post pk, I passed post pk in url params and get in answer post view to save in form instance. This should work now!

  • Related