dev-jim
dev-jim

Reputation: 2524

how to save many to many fields in django create view

Here is my models:

class Category(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255, blank=True,default=None)
    desc = models.TextField(blank=True, null=True )
    .....

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    categories = models.ManyToManyField(Category, blank=True, through='CatToPost')
     .......

class CatToPost(models.Model):
    post = models.ForeignKey(Post)
    category = models.ForeignKey(Category)

The problem now I can't make it work to save the many-to-many field by using the generic create view.

Cannot set values on a ManyToManyField which specifies an intermediary model. Use posts.CatToPost's Manager instead.

In SO there was a similar problem that suggest override the form_valid method to manually create the relation, but it didn't works for me.

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

        for cat in form.cleaned_data['categories']:

            cate = CatToPost()
            cate.post = self.object
            cate.category = cat
            cate.save()
        return super(AddStoryForm, self).form_valid(form)

The error:

Cannot assign "": "Post" instance isn't saved in the database.

Seem self.object = form.save(commit=False) not saving in the db, so the Post ID wasn't created.

But when I turn self.object = form.save(commit=True) , I still got the previous error occurred again.

Any idea how can I overcome this problem?

Upvotes: 2

Views: 2649

Answers (1)

Scott Staniewicz
Scott Staniewicz

Reputation: 742

I also had a similar problem to the answer you listed. For me what worked is to add self.object.save() after self.object = form.save(commit=False)

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

    for cat in form.cleaned_data['categories']:

        cate = CatToPost()
        cate.post = self.object
        cate.category = cat
        cate.save()
    return super(AddStoryForm, self).form_valid(form)

Upvotes: 3

Related Questions