代码之家  ›  专栏  ›  技术社区  ›  Andrew

如何为ForeignKey使用默认字段值?

  •  1
  • Andrew  · 技术社区  · 4 年前

    我刚刚开始学习Django并用它建立一个简单的博客。 所以我有两个模型 Post PostStatistics 。每当我添加新帖子时,我希望PostStatistics包含所有指定的默认值。我怎样才能正确地做到这一点?

    模型。py

    class PostStatistics(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid4)
        post_views = models.IntegerField(default=0)
        post_likes = models.IntegerField(default=0)
        post_favorites = models.IntegerField(default=0)
    
    class Post(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid4)
        user = models.ForeignKey(UserProfile, null=True, on_delete=models.CASCADE)
        statistics = models.ForeignKey(PostStatistics, null=True, on_delete=models.CASCADE)
        title = models.CharField(max_length=200)
        body = RichTextField(blank=True, null=True)
        draft = models.BooleanField(default=False)
    

    意见。py

    def add_post(request: HttpRequest):
        form = PostForm(request.POST)
        is_draft = True if form.data.get("draft") == "on" else False
        post = Post(
            title=form.data["title"],
            body=form.data["post"],
            user=request.user,
            draft=is_draft,
            statistics = PostStatistics() -> this is not correct
        )
        post.save()
        return redirect("post")
    

    在我得到 FOREIGN KEY constraint failed .

    1 回复  |  直到 4 年前
        1
  •  1
  •   willeM_ Van Onsem    4 年前

    创建一个新的:

    def add_post(request: HttpRequest):
        form = PostForm(request.POST)
        is_draft = form.data.get('draft') == 'on'
        post_statistics = PostStatistics.objects.create()
        Post.objects.create(
            title=form.data['title'],
            body=form.data['post'],
            user=request.user,
            draft=is_draft,
            statistics = post_statistics
        )
        return redirect('post')

    然而,将统计数据存储在单独的模型中没有多大意义,因为存在明确的一对一关系,因此统计数据可以存储在单独的模型中 Post 模型

    此外,还可以使用表单验证输入,并创建对象(或至少部分对象)。因此,更好的建模方法可能是:

    from django.conf import settings
    
    class Post(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid4)
        user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, editable=False)
        title = models.CharField(max_length=200)
        body = RichTextField(blank=True, null=True)
        draft = models.BooleanField(default=False)
        post_views = models.IntegerField(default=0, editable=False)
        post_likes = models.IntegerField(default=0, editable=False)
        post_favorites = models.IntegerField(default=0, editable=False)

    然后和一个 ModelForm 让表格进行所有适当的验证和清理:

    from django.contrib.auth.decorators import login_required
    
    @login_required
    def add_post(request: HttpRequest):
        if request.method == 'POST':
            form = PostForm(request.POST)
            if form.is_valid():
                form.instance.user = request.user
                form.save()
                return redirect('post')
        else:
            form = PostForm()
        return render(request, 'name-of-some-template.html', {'form': form})

    笔记 :通常最好利用 settings.AUTH_USER_MODEL  [Django-doc] 参考用户模型,而不是使用 User model [Django-doc] 直接地有关更多信息,请参见 referencing the User model section of the documentation .


    笔记 :您可以将视图限制为具有 @login_required decorator [Django-doc] .