Django CreateView给出了一个错误“需要有一个字段值”......“才能使用这种多对多关系。”

时间:2013-07-26 03:28:28

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

我正在练习Django的FormViews。

在这个应用程序中,我正在创建一个创建博客帖子的PostCreate视图。

以下是我的代码:

models.py

class Post(models.Model):
    user = models.ForeignKey(User)
    post_title = models.CharField(max_length=200)
    post_content = models.CharField(max_length=500)

class Tag(models.Model):
    name = models.CharField(max_length=64, unique=True)
    posts = models.ManyToManyField(Post)

forms.py

class PostForm(forms.ModelForm):
    post_title = forms.CharField(
        label=u'Title',
        widget=forms.TextInput(attrs={'size':64})
    )
    post_content = forms.CharField(
        label=u'Content',
        widget=forms.TextInput(attrs={'size':128})
    )
    tags = forms.CharField(
        label=u'Tags',
        required=True,
        widget=forms.TextInput(attrs={'size':64})
    )
    class Meta:
        model = Post
        exclude = ('user', 'post_date')

views.py

class PostCreate(CreateView):
    template_name = 'app_blog/post_save_form.html'
    model = Post
    form_class = PostForm

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.user = self.request.user

        tag_names = form.cleaned_data['tags'].split()
        for tag_name in tag_names:
            tag, dummy = Tag.objects.get_or_create(name=tag_name)
            self.object.tag_set.add(tag)

        return super(PostCreate, self).form_valid(form)

当我尝试将帖子(Test Post 1)保存到数据库中时,它会给我一个错误:

在可以使用多对多关系之前,

需要为字段“post”设置值。

看起来问题是由views.py中的行引起的,其中我拆分了“tag”字段并将标记添加到post对象的tag_set字段。我想这个逻辑不应该包含在form_valid方法中......但是我不知道应该在哪里实现这个...

任何帮助将不胜感激:)谢谢

2 个答案:

答案 0 :(得分:9)

不,这不是问题所在。问题是你还没有保存Post对象,所以你不能用它创建多对多关系(因为在幕后,m2m只是一个带有两个实体的外键的链接表)。解决方案是首先保存self.object

答案 1 :(得分:7)

您应该在分配用户后保存对象,然后使用m2m关系执行操作:

self.object = form.save(commit=False)  # Not saved to database.
self.object.user = self.request.user
self.object.save()  # Saved.

tag_names = form.cleaned_data['tags'].split()
for tag_name in tag_names:
    tag, dummy = Tag.objects.get_or_create(name=tag_name)
    self.object.tag_set.add(tag)