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

时间:2018-05-24 21:26:00

标签: python django database django-models django-class-based-views

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

上下文:我正在编写一个处理群组,帖子和用户的Django-App。帖子条目包含组和用户的外键(帖子必须属于组和用户)。我希望用户能够从组页面本身向组添加帖子 - 即,当他们访问此新帖子的CreateView表单时,应该没有“组”字段。

我的问题:我想用一个CreateView类保存一个新的post对象,其中包含一个幕后插件(来自slug)和User(来自self.request.user) )。通常,我使用form_valid()方法来执行此操作,并且它适用于插入User对象;但是,我无法弄清楚为什么我的Group对象不会保存。

其他一些信息

  • 我知道我能够成功地从kwargs中的slug中获取Group对象。我已将此对象分配给get()方法中的变量self.form_group,并且我已确认对象的“类型”是我的Group类的正确实例。

  • 我尝试在form_valid()方法中“获取”Group对象:仍然没有运气。

  • 我分别在form_valid()方法中尝试了注释和未注释的代码块。

模型

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

感谢您的帮助,这让我疯了!

2 个答案:

答案 0 :(得分:0)

我认为你的错误是试图调用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)

换句话说,在您添加了组和用户保存帖子后,表单会再次保存,不会覆盖您的第一次保存。这是我的建议:

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

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

答案 1 :(得分:0)

结果证明这不是视图或模型文件中的问题,而是模板中的问题。我的表单是将数据发送到我的常规新帖子' CreateView,这就是为什么我的form_valid()方法从未被调用过,而且从未插入过Group的原因。