W. Reyna
W. Reyna

Reputation: 724

Getting "NOT NULL constraint" when submitting form through view. Works fine when adding through /admin

I'm creating a simple ratemyteacher/prof clone. The issue is that when going trying to add a Review object via my view, I get NOT NULL constraint failed: rate_review.review_id (app name is rate). It works fine when adding via /admin. Also, adding other models work fine.

Here's the view where it occurs:

def add_review(request, teacher_id):
    form = ReviewForm()
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            ip = request.META.get('HTTP_CF_CONNECTING_IP')
            if ip is None:
                ip = request.META.get('REMOTE_ADDR')
            form.customSave()
            messages.success(request, 'Review added.')
        else:
            form = ReviewForm(request.POST)
            return render(request, 'rate/add_review.html', {'form': form})
    return render(request, 'rate/add_review.html', {'form': form})

Here is the form (truncated to exclude loads). I'm using this to render forms:

<form method="POST">{% csrf_token %}
            <div class="field">
                <label class="label">Stars (whole numbers only)</label>
                <div class="control">
                    {% render_field form.stars class+="input" %}
                </div>
            </div>
            <div class="field">
                <label class="label">Review subject</label>
                <div class="control">
                    {% render_field form.subject class+="input" %}
                </div>
            </div>

            <div class="field">
                <label class="label">Review text</label>
                <div class="control">
                    {% render_field form.text class+="textarea" placeholder="Review text" rows="10" %}
                </div>
            </div>

            <div class="field">
                <label class="label">Username</label>
                <div class="control">
                    {% render_field form.author class+="input" placeholder="eg. ReviewerMan21, John Smith" %}
                </div>
            </div>


            <button type="submit" class="button">Add review</button>
        </form>

My models.py:

class Teacher(models.Model):
    grade = models.IntegerField()
    name = models.CharField(max_length=35)
    subject = models.CharField(max_length=50)
    ip = models.CharField(max_length=14)
    approved = models.BooleanField(null=True, blank=True)

class Review(models.Model):
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
    text = models.TextField()
    subject = models.CharField(max_length=120)
    author = models.CharField(max_length=35)
    ip = models.CharField(max_length=14)
    date = models.DateTimeField(auto_now_add=True)
    stars = models.PositiveSmallIntegerField()

My forms.py:

from django import forms
from .models import Teacher, Review, Grade
from django.core import validators

class ReviewForm(forms.ModelForm):
    class Meta:
        model = Review
        fields = ('subject', 'text', 'stars', 'author')

    def customSave(self, ip):
        lv = self.save(commit=False)
        lv.ip = ip
        lv.save()
        return lv

class TeacherForm(forms.ModelForm):
    class Meta:
        model = Teacher
        fields = ('subject', 'name', 'grade')

    def customSave(self, ip):
        lv = self.save(commit=False)
        lv.ip = ip
        lv.save()
        return lv

Things I've tried:

Edit: I've fixed (thanks to the answer below) by changing customSave in ReviewForm to this, and then passing the teacher variable from my view:

    def customSave(self, ip, teacher):
        lv = self.save(commit=False)
        lv.ip = ip
        lv.teacher = teacher
        lv.save()
        return lv

Upvotes: 1

Views: 28

Answers (1)

Esteban
Esteban

Reputation: 2513

Your error shows that review_id is None (null). I notice that your ForeignKey field to Teacher on the Review model is named review instead of teacher, which would indicate the review_id really belongs to a Teacher object.

I noticed the first line of your view add_review method, you get a Teacher object but never do anything with it. Did you intent to set the teacher ('review' field) on your newly created review to this teacher instance?

Upvotes: 1

Related Questions