本文介绍了NOT NULL约束失败,Django CreateView失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在这个项目上实现两个目标。首先,我想将登录用户另存为审阅者。其次,我想将外键中的律师价值传递给复查表。 (通过这种方式,用户可以查看单击律师详细信息页面上的审阅链接,然后查看该律师,而不是其他任何人。)

I would like to accomplish two goals on this project. First, I would like to save the logged-in user as the reviewer. Second, I want to pass the lawyer value from the foreignkey into the review form. (This way, the user can review click on a review link on the lawyer's detail page and review that lawyer and no one else.)

我一直在追求第一个目标,出现此错误。

I keep getting on the first goal, with this error.

错误

IntegrityError at /lawyers/karlyn-rosemarie-hylton/review/
NOT NULL constraint failed: lawyers_review.reviewer_id

Can有人请解释我在做什么错以及如何解决?

Can someone please explain what I am doing wrong and how to fix it?

第二个目标似乎与第一个目标非常相关。我没有任何错误。但我想确保自己做得对。但是,直到我通过第一个错误后,我才能告诉。

The second goal seems to be very related to the first goal. I am not getting any errors for it. But I want to make sure that I am doing it right. However, I won't be able to tell until I get passed the first error.

任何不被卡住的帮助都将受到赞赏。

Any help getting unstuck is much appreciated.

models.py

models.py

from django.db import models
from django.urls import reverse
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User


class Lawyer(models.Model):
    name = models.CharField(max_length=55,
                            default='')
    picture = models.ImageField(upload_to='media/lawyers/pictures',
                                default='')
    slug = models.SlugField()

    def average_rating(self):
        all_ratings = map(lambda x: x.rating, self.review_set.all())
        return np.mean(all_ratings)

    def save(self, *args, **kwargs):
        self.slug = (slugify(self.name))
        super(Lawyer, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('lawyers:detail', kwargs={'slug': self.slug})

    def __str__(self):
        return self.name


class Review(models.Model):
    RATING_CHOICES = (
        (1, '1'),
        (2, '2'),
        (3, '3'),
        (4, '4'),
        (5, '5'),
    )
    lawyer = models.ForeignKey(Lawyer,
                                null=True)
    created = models.DateTimeField(auto_now_add=True)
    reviewer = models.ForeignKey(User)
    title = models.CharField(max_length=55,
                                default='')
    comment = models.TextField()
    rating = models.IntegerField(choices=RATING_CHOICES)

    def __str__(self):
        return self.lawyer.name

views.py

from django.shortcuts import render, get_object_or_404
from django.views.generic import (CreateView,
                                    DetailView,
                                    ListView)


from django.contrib.auth.models import User


from .models import Lawyer, Review


class AddLawyerView(CreateView):
    model = Lawyer
    fields = ['name', 'picture']

    def post_valid(self, form):
        lawyer = form.save(Commit=False)
        lawyer.picture = form.cleaned_data['picture']
        return super(AddLawyerView, self).form_valid(form)


class LawyerDetail(DetailView):
    model = Lawyer


class LawyerList(ListView):
    model = Lawyer


class AddReviewView(CreateView):
    model = Review
    fields = ['rating', 'title', 'comment']

    def post_valid(self, form):
        review = form.save(Commit=False)
        review.lawyer = get_object_or_404(Lawyer,
                                            slug=self.kwargs.get('slug'))
        review.reviewer = User.objects.get(user=self.request.user)
        return super(AddReview, self).form_valid(form)

urls.py

from django.conf.urls import url


from .views import (AddLawyerView,
                    LawyerDetail,
                    LawyerList,
                    AddReviewView)


urlpatterns = [
    url(r'^add-lawyer',
        AddLawyerView.as_view(),
        name = 'add-lawyer'),


    url(r'^(?P<slug>[\w-]+)/$',
        LawyerDetail.as_view(),
        name = 'detail'),


    url(r'^$',
        LawyerList.as_view(),
        name = 'list'),


    url(r'^(?P<slug>[\w-]+)/review/$',
        AddReviewView.as_view(),
        name = 'add-review'),
]

使用@Alasdair和@Sachin的反馈uk reja,我回去做了一些更正。我将提交更改为提交,将 post_valid更改为 form_valid。我还做了一个小调整,以简化视图。纠正和正常工作的AddReviewView如下。上面有一个错误。

Using the feedback from @Alasdair and @Sachin Kukreja , I went back and made some correction. I changed "Commit" to "commit" and "post_valid" to "form_valid". I also made one minor tweak to simplify the view. The corrected and working AddReviewView is below. The one with mistakes is above.

谢谢大家!

工作视图:

class AddReviewView(CreateView):
    model = Review
    fields = ['rating', 'title', 'comment']

    def form_valid(self, form):
        review = form.save(commit=False)
        review.lawyer = get_object_or_404(Lawyer,
                                            slug=self.kwargs.get('slug'))
        review.reviewer = self.request.user
        return super(AddReviewView, self).form_valid(form)


推荐答案

您在这里有一个错字,您覆盖了 form_valid ,但是您写了 post_valid

You have a typo there, you are overriding form_valid but you have written post_valid.

def form_valid(self, form):
    review = form.save(Commit=False)
    review.lawyer = get_object_or_404(Lawyer,
                                        slug=self.kwargs.get('slug'))
    review.reviewer = User.objects.get(user=self.request.user)

    # save and return HttpResponse
    review.save()
    return HttpResponseRedirect(self.get_success_url())

但是, super 调用仍将调用父类的 form_valid 仍然会引发错误。我认为您可以将评论保存在此重写的方法中,并返回基类返回的内容,即 return HttpResponseRedirect(self.get_success_url())

But, the super call will still call the parent class' form_valid which will still raise the error. I think you can save the review in this overriden method and return what the base class returns i.e. return HttpResponseRedirect(self.get_success_url())

引用:,在ModelFormMixin中

Ref: form_valid in FormMixin class, form_valid in ModelFormMixin class

这篇关于NOT NULL约束失败,Django CreateView失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 17:13