简体   繁体   English

Django NOT NULL约束失败

[英]Django NOT NULL constraint failed

I am just starting to learn about Django and I am running into an issue. 我刚刚开始学习Django,我遇到了一个问题。 I have a modelFormSet that is meant to add 3 choices to a question you create. 我有一个modelFormSet,用于为您创建的问题添加3个选项。 I have no issue when I am not using the modelFormset and only adding one question but when I try to iterate through a modelsFormset and assign each choice to the question that was just created I get the following error: 当我没有使用modelFormset并且只添加一个问题但是当我尝试迭代modelsFormset并将每个选项分配给刚刚创建的问题时,我没有问题我得到以下错误:

NOT NULL constraint failed: polls_choice.question_id

I think it has something to do with the question_id not being passed to the choice model but I am not sure how to fix it. 我认为这与question_id没有传递给选择模型有关,但我不确定如何解决它。 I have run fresh migrations and I don't think I can set blank or null to True since I need the choice and question to be related. 我已经运行了新的迁移,我认为我不能将空白或null设置为True,因为我需要选择和问题相关。 Thank you in advance for your help! 预先感谢您的帮助!

Models 楷模

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    assigned_to = models.ManyToManyField(User)
    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text

Forms 形式

class CreateQuestion(forms.ModelForm):
    class Meta:
        model = Question
        fields = ('question_text', 'assigned_to', 'pub_date',)


class AddChoices(forms.ModelForm):
    class Meta:
        model = Choice
        fields = ('choice_text',)

View 视图

def create_question(request):
    choices_formset = modelformset_factory(Choice, form=AddChoices, fields=('choice_text',), extra=3)
    if request.method == 'POST':
        question_form = CreateQuestion(data=request.POST)
        choice_form = choices_formset(request.POST, request.FILES)
        if question_form.is_valid and choice_form.is_valid:
            question = question_form.save()
            for choice in choice_form:
                choice.question = question
                choice.save()
            return HttpResponseRedirect(reverse('polls:index'))
        else:
            return render(request, 'polls/createquestion.html', {'question_form': question_form,
                                                                 'choice_form': choice_form, })
    else:
        question_form = CreateQuestion()
        choice_form = choices_formset(queryset=Choice.objects.none(),)
        return render(request, 'polls/createquestion.html', {'question_form': question_form,
                                                             'choice_form': choice_form, })

When you loop through for choice in choice_form , each item is a form, so setting the question attribute doesn't work. 当您for choice in choice_form循环for choice in choice_form ,每个项目都是一个表单,因此设置question属性不起作用。

Instead, you should save with commit=False , set the question, then save the object to the db. 相反,您应该使用commit=False保存,设置问题,然后将对象保存到数据库。

for form in choice_form:
    choice = form.save(commit=False)
    choice.question = question
    choice.save()

Problem is here: 问题在这里:

            for choice in choice_form:
                choice.question = question
                choice.save()

You're iterating here over AddChoices forms, not over Choice objects. 您在这里通过AddChoices表单进行迭代,而不是在Choice对象上进行迭代。 That mean, you're saving question as an attribute of form, not as attribute of model instance and that won't propagate into model instance. 这意味着,您将问题保存为表单的属性,而不是模型实例的属性,并且不会传播到模型实例中。

To fix it you can try: 要修复它,您可以尝试:

            for form in choice_form:
                choice = form.save(commit=False)
                choice.question = question
                choice.save()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM