使用 CreateView 在 Django 中保存外键(不是用户对象)

Saving a Foreign Key (that isn't a User object) in Django using a CreateView

TL;DR:我想使用 CreateView class 保存外键——我可以保存我的用户组,但不能保存我自己的模型对象。

Context:我正在编写一个处理组、Posts 和用户的 Django 应用程序。 Post 条目包含组和用户的外键(post 必须属于组和用户)。我希望用户能够从群组页面本身向群组添加 post——即,当他们访问这个新 post 的 CreateView 表单时,不应该有 'Group'场地。

我的问题:我想用CreateView class保存一个新的post对象,并在幕后插入组(来自 slug)和用户(来自 self.request.user)。通常,我使用 form_valid() 方法来执行此操作,它可以很好地插入 User 对象;但是,我不明白为什么我的组对象不会保存。

一些其他信息

型号

class Post(models.Model):
    user = models.ForeignKey(User, on_delete = models.CASCADE, related_name = 'posts')
    title = models.CharField(max_length = 100,default = '')
    created_at = models.DateTimeField(auto_now = True)
    post_text = models.TextField()
    post_text_html = models.TextField(editable = False) 
    group = models.ForeignKey(Group, on_delete = models.CASCADE, related_name = 'posts', null = True, blank = True)

-

class Group(models.Model):
     name = models.CharField(max_length = 255, unique = True)
     slug = models.SlugField(allow_unicode = True, unique = True)
     description = models.CharField(max_length = 5000, blank = True, default = '')
     description_html = models.TextField(editable = False, blank = True, default = '')  # Cannot be Edited
     members = models.ManyToManyField(User, through = 'GroupMember')

Views.py

 class CreatePostInGroup(LoginRequiredMixin, SelectRelatedMixin, generic.CreateView):
    model = Post
    fields = ['title', 'post_text']
    template_name = 'posts/post_in_group_form.html'

    def get(self, request, *args, **kwargs):
        print(self.kwargs)
        print(type(self.request.user))
        self.form_group = get_object_or_404(Group, slug=self.kwargs.get('slug'))
        print(type(self.form_group))
        return super(CreatePostInGroup, self).get(request, *args, **kwargs)

    def form_valid(self, form):
        form.instance.user = self.request.user
        try:
            form.instance.group = self.form_group
        except:
            return Http404
        return super(CreatPostInGroup, self).form_valid(form)

    def get_context_data(self, *args, **kwargs):
        context = super(CreatePostInGroup, self).get_context_data(*args, **kwargs)
        context['group'] = Group.objects.get(slug=self.kwargs.get('slug'))
        return context

感谢您的帮助,这让我抓狂!

我认为您的错误是试图调用 super 方法。本质上,如果您查看 form_valid 的作用:

def form_valid(self, form):
    """If the form is valid, save the associated model."""
    self.object = form.save()
    return super().form_valid(form)

换句话说,在您保存 post 并添加组和用户后,表单会再次保存而不保存,覆盖您的第一次保存。以下是我的建议:

self.object = form.save(commit = False)
self.object.group = self.form_group
self.object.user = self.request.user
self.object.save()

然后使用return redirect()重定向到您需要去的地方

事实证明问题不在视图或模型文件中,而是在模板中。我的表单将数据发送到我的常规 'new post' CreateView,所以这就是为什么我的 form_valid() 方法从未被调用并且该组从未被插入的原因。