Django CreateView gives an error "needs to have a value for field "..." before this many-to-many relationship can be used."

user2492270 picture user2492270 · Jul 26, 2013 · Viewed 8.6k times · Source

I'm practicing with Django's FormViews.

In this app, I'm creating a PostCreate view that creates a blog post.

Here are my codes:

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)

When I try saving a post (Test Post 1) into a database, it gives me an error:

needs to have a value for field "post" before this many-to-many relationship can be used.

It looks like the problem is caused by lines in views.py where I split the "tag" field and add the tags to the post object's tag_set field. I suppose this logic should not be included in the form_valid method... but I don't know where else this should be implemented..

Any help would be greatly appreciated :) Thanks

Answer

Daniel Roseman picture Daniel Roseman · Jul 26, 2013

No, that's not what the problem is. The problem is that you haven't saved the Post object yet, so you can't create a many-to-many relationship with it (because under the hood, m2m is just a linking table with foreign keys to both entities). The solution is to save self.object first.