【问题标题】:Django create postDjango创建帖子
【发布时间】:2022-01-20 19:56:17
【问题描述】:

我正在尝试在论坛上创建一个新帖子,它确实有效,我也在打印表单是否有效,但是当我在帖子没有发布后去检查时。在管理页面中,帖子在那里,已获批准,但缺少标签和类别字段。它们是在创建帖子时添加的,否则我会收到错误消息。但是我必须在管理页面中手动添加它们才能将帖子发布到论坛。

这是我在模型中的帖子

class Post(models.Model):
    title = models.CharField(max_length=400)
    slug = models.SlugField(max_length=400, unique=True, blank=True)
    user = models.ForeignKey(Author, on_delete=models.CASCADE)
    content = HTMLField()
    categories = models.ManyToManyField(Category)
    date = models.DateTimeField(auto_now_add=True)
    approved = models.BooleanField(default=True)
    tags = TaggableManager()
    comments = models.ManyToManyField(Comment, blank=True)
    # closed = models.BooleanField(default=False)
    # state = models.CharField(max_length=40, default="zero")

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

这是我的意见.py

@login_required
def create_post(request):
    context = {}
    form = PostForm(request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            print("\n\n form is valid")
            author = Author.objects.get(user=request.user)
            new_post = form.save(commit=False)
            new_post.user = author
            new_post.save()

            return redirect('forums')
        
    context.update({
            'form': form,
            'title': 'Create New Post'
    })
    return render(request, 'forums/create_post.html', context)

html 很简单,可以测试一下。

<form method="POST">
                            {% csrf_token %}    
                            {{form|crispy}}
                            <!-- Submit Post -->
                            <input type="submit" value="Save">
                        </form>

任何帮助将不胜感激

【问题讨论】:

    标签: python html django django-models django-forms


    【解决方案1】:

    new_post = form.save(commit=False) 这行不会根据docs 保存多对多关系。解决方法

    new_post = form.save(commit=False)
    new_post.user = author
    new_post.save()
    form.save_m2m()
    

    摘自docs

    使用 commit=False 的另一个副作用是当您的模型具有 与另一个模型的多对多关系。如果您的模型有 多对多关系,并且您在保存时指定 commit=False 表单,Django 无法立即保存表单数据 多对多的关系。这是因为无法保存 一个实例的多对多数据,直到该实例存在于 数据库。

    要解决此问题,每次保存表单时都使用 commit=False,Django 将 save_m2m() 方法添加到您的 ModelForm 子类。手动保存由 表单,您可以调用 save_m2m() 来保存多对多表单数据。

    我认为这并不能解决所有问题,但请尝试一下。

    【讨论】:

    • 返回错误:'Post'对象没有属性'save_m2m'
    • 对不起,表格是应该有save_m2m的。我刚刚编辑了答案。
    • 然后返回需要有字段“id”的值才能使用这种多对多关系。
    • 您能否将 PostForm 类添加到您的问题中。
    • 我设法通过在保存 new_post 后添加 form.save_m2m() 来解决它。感谢您的帮助
    【解决方案2】:

    ModelFormcommit=False时无法保存多对多关系的原因是它没有在数据库端创建Post,因此没有可用于添加的主键多对多关系。

    你可以使用.save_m2m()来保存多对多关系在你保存了包裹在表单中的实例之后,但也许更优雅的解决方案是将request.user附加到包裹在表单中的实例上,然后保存表单,此后表单也会在同一个函数调用中保存多对多关系,所以:

    from django.shortcuts import get_object_or_404
    
    # …
    
    if form.is_valid():
        form.instance.user = get_object_or_404(Author, user=request.user)
        form.save()

    可能值得将.user 字段重命名为.author,因为现在它暗示它正在存储User 对象,而不是Author 对象。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多