You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Django影评提交与更新功能中的IntegrityError问题

Hey there, let's figure out why your review form is throwing those errors and fix it up.

First, let's unpack the error messages:

  • The first reviews.DoesNotExist makes sense—it just means the user hasn't submitted a review for this movie yet, so your get() call can't find an existing record.
  • The real problem comes in the except block: when you create a new reviews instance, you're not setting the movie and user fields. Since these are required ForeignKeys in your model, the database rejects the save because movie_id (and user_id) can't be null.

Here's how to fix this, step by step:

1. Fix the new review creation in the except block

You need to associate the new review with both the current movie and the logged-in user. Update your views.py code like this:

First, make sure you import the necessary modules (if you haven't already):

from django.core.exceptions import ObjectDoesNotExist
from .models import reviews, details  # Ensure details is your Movie model
from django.contrib.auth.decorators import login_required

Then modify the user_reviews view:

@login_required  # Add this to ensure only logged-in users can submit reviews
def user_reviews(request, movies_id):
    url = request.META.get('HTTP_REFERER')
    if request.method == 'POST':
        try:
            # Try to get existing review for this user and movie
            ureview = reviews.objects.get(movie__id=movies_id, user__id=request.user.id)
            form = ReviewForm(request.POST, instance=ureview)
            form.save()
            return redirect(url)
        except ObjectDoesNotExist:
            form = ReviewForm(request.POST)
            if form.is_valid():
                data = reviews()
                # Set the required ForeignKey fields (this fixes the null error)
                data.movie = details.objects.get(id=movies_id)  # Link to the correct movie
                data.user = request.user  # Link to the logged-in user
                # Set the other fields from the form
                data.title = form.cleaned_data['title']
                data.review = form.cleaned_data['review']
                data.rating = form.cleaned_data['rating']
                data.ip = request.META.get('REMOTE_ADDR')
                data.save()
                return redirect(url)
    # Add handling for GET requests (when user first loads the page)
    else:
        # Optionally pre-fill form if user has an existing review
        try:
            existing_review = reviews.objects.get(movie__id=movies_id, user__id=request.user.id)
            form = ReviewForm(instance=existing_review)
        except ObjectDoesNotExist:
            form = ReviewForm()
        return render(request, 'your_review_template.html', {'form': form, 'movies_id': movies_id})

2. Why this works:

  • @login_required ensures request.user is always a valid logged-in user, preventing issues with anonymous users trying to submit reviews.
  • We explicitly set data.movie to the details object matching movies_id, and data.user to request.user. This populates the required movie_id and user_id fields in the database, fixing the IntegrityError.
  • Added handling for GET requests—your original code didn't account for this, which could lead to unexpected behavior when users first navigate to the review page.

Bonus: Use ModelForm for cleaner code

Your ReviewForm should probably be a ModelForm, which simplifies creating/updating instances without manually assigning fields. Here's how that would look:

In forms.py:

from django import forms
from .models import reviews

class ReviewForm(forms.ModelForm):
    class Meta:
        model = reviews
        fields = ['title', 'review', 'rating']  # Fields users can edit

Then your view can be simplified even more:

@login_required
def user_reviews(request, movies_id):
    url = request.META.get('HTTP_REFERER')
    movie = details.objects.get(id=movies_id)  # Get the movie once
    try:
        existing_review = reviews.objects.get(movie=movie, user=request.user)
    except ObjectDoesNotExist:
        existing_review = None

    if request.method == 'POST':
        form = ReviewForm(request.POST, instance=existing_review)
        if form.is_valid():
            review = form.save(commit=False)
            review.movie = movie
            review.user = request.user
            review.ip = request.META.get('REMOTE_ADDR')
            review.save()
            return redirect(url)
    else:
        form = ReviewForm(instance=existing_review)
    
    return render(request, 'your_review_template.html', {'form': form, 'movie': movie})

This version is cleaner, less error-prone, and follows Django best practices.

Final Checks:

  • Confirm your details model is correctly imported in views.py.
  • Ensure your template is passing the correct movies.id to the form's action URL (your existing HTML looks okay for this).
  • Test both submitting a new review and updating an existing one to confirm the fix works.

内容的提问来源于stack exchange,提问作者Abin Benny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 22:47:30