Search code examples
pythondjangomany-to-manyblogs

Django Form for ManyToMany fields


I have to design a form for add a new post in my blog.

Model.py

class Category(models.Model):
    title = models.CharField(max_length=200)
    ...
    ...
    def __unicode__(self):
        return self.title

class Post(models.Model):

    title = models.CharField(max_length=80)
    pub_date = models.DateTimeField()
    text = models.CharField(max_length=140)
    ...

    categories = models.ManyToManyField(Category, blank=True, null=True, through='CategoryToPost')

    def __unicode__(self):
        return self.title

class CategoryToPost(models.Model):

    post = models.ForeignKey(Post)
    category = models.ForeignKey(Category)

Views.py

def add_post(request):

form = PostForm()
if request.method == "POST":
    form = PostForm(request.POST)
    if form.is_valid():
        form = PostForm(request.POST)
        post = form.save(commit=False)
        post.author = User.objects.get(id = request.user.id)
        post.categories = post.categorytopost_set
        ...
        post.save()
        return HttpResponseRedirect('/')
    else:
        return render(request, 'add_post.html', {'error': True, 'form': form})
else:
    return render(request, 'add_post.html', {'error': True, 'form': form})

Form.py

class PostForm(ModelForm):

    class Meta:
        model = Post
        fields = ('title', 'text', 'categories', 'tags')

When I try to insert catogories in new post from template "add_post.html" there is always an error refers to ManyToMany:

"Cannot set values on a ManyToManyField which specifies an intermediary model. Use CategoryToPosts Manager instead."


Solution

  • The problem is related to this instruction :

     post.categories = post.categorytopost_set
    

    From the Django documentation:

    Unlike normal many-to-many fields, you can’t use add, create, or assignment (i.e., beatles.members = [...]) to create relationships.

    In your scenario you should manually create the CategoryToPostobject with both references to Post and Category and save it.