IntegrityError, ограничение NOT NULL не удалось

Я хочу добавить теги к сообщениям в своем приложении Django.

Я могу добавить теги через интерфейс администратора, но когда я пытаюсь сделать это через созданную мной форму, я получаю IntegrityError.

Я не мог найти решение в существующих темах с той же ошибкой. Я пробежал makemigrations и migrate.

От models.py:

class Post(models.Model):
    title = models.CharField(null=False, blank=False)
    text = models.TextField()

class Tag(models.Model): 
    post = models.ForeignKey('my_app.Post', on_delete=models.CASCADE, related_name='tags')
    tag_text = models.CharField()

Вид:

def post_add_tags(request, pk): 
    post= get_object_or_404(Post, pk=pk)
    if request.method == "POST": 
        form = TagForm(request.POST)
        if form.is_valid():
            tag = form.save()
            tag.post= post
            tag.save()
            return redirect("single_post_view", pk=post.pk)
    else: 
        form = TagForm()
    return render(request, "add_tags.html", {"form": form})

Форма от forms.py:

class TagForm(forms.ModelForm): 
    class Meta:
        model = Tag
        fields = ["tag_text"]

Шаблон:

<form method="POST"> {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="save btn btn-default">Add tags</button>
</form>

Ошибка:

IntegrityError в /post/4/add_tags/

Ошибка ограничения NOT NULL: my_app_tag.post_id

Я использую Django версии 2.2, Python 3.6.8.


person Zaff    schedule 11.06.2019    source источник
comment
эта строка tag = form.save(), она должна быть tag = form.save(commit=False)   -  person Nalin Dobhal    schedule 11.06.2019


Ответы (1)


не делайте save form пока не заполните все обязательные поля, особенно foreign keys :

def post_add_tags(request, pk): 
    post= get_object_or_404(Post, pk=pk)
    if request.method == "POST": 
        form = TagForm(request.POST)
        if form.is_valid():
            tag = form.save(commit=False)
            tag.post= post
            tag.save()
            return redirect("single_post_view", pk=post.pk)
    else: 
        form = TagForm()
    return render(request, "add_tags.html", {"form": form})
person katoozi    schedule 11.06.2019
comment
Спасибо, это сработало, но почему? В документах говорится, что если вы вызовете save() с commit=False, то он вернет объект, который еще не был сохранен в базе данных. В этом случае вы должны вызвать save() для результирующего экземпляра модели. но в таком случае, почему я не мог сохранить его сразу? - person Zaff; 11.06.2019
comment
потому что post внешний ключ будет null - person katoozi; 11.06.2019
comment
О, теперь я понял. Спасибо еще раз! - person Zaff; 11.06.2019