Question

What i want to do, is give the people to tag a post by writing in a charfield, separating the tags with ','.

now this is my model (just the part we care)

class Tag(models.Model):
    name = models.CharField(max_length=100, default='')


    def __unicode__(self):
        return "%s" % (self.name)


class Post(models.Model):
    .....
    tags = models.ManyToManyField(Tag,blank=True, null=True)

then i've a form

class PostForm(ModelForm):
...
    tags = forms.CharField(label=(u'Tags '))

    class Meta:
        model = Publication

    def __init__(self, *args, **kwargs):
        self.helper = FormHelper()
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', 'Invia'))
        self.helper.form_class = 'form-horizontal'

        super(PostForm, self).__init__(*args, **kwargs)

then i've my createView, to which i overridden the form_valid method to make string parsing

class PostAdd(CreateView):
    template_name = 'form.html'
    form_class = PostForm
    success_url='/'

    def form_valid(self, form):
        pub = form.save(commit=False)
        pub.tags=None
        pub.save()

        tags=str(self.request.POST.get('tags'))
        tags = tags.split(',')
        tl=[]
        for tag in tags:
            tl.append(Tag.objects.get_or_create(name=tag))
        pub.tags.add(tl)

        form.save_m2m()
        return HttpResponseRedirect(self.get_success_url())

what i did is to save the form with commit=False in order to change the value of the tags. I tried with None or [] but in all the cases what i've back is an error on the line of the pub.tags=None assignme:

'Post' instance needs to have a primary key value before a many-to-many relationship can be used.
Was it helpful?

Solution

Here you are settings "tags" attribute to None, but your publication does not have a Primary Key yet, so the many to many relationship is having a hard time.

What you have to do is to save it first.

You will find more about this here

def form_valid(self, form):
    pub = form.save(commit=False)
    pub.save()
    pub.tags=None


    tags=str(self.request.POST.get('tags'))
    tags = tags.split(',')
    tl=[]
    for tag in tags:
        tl.append(Tag.objects.get_or_create(name=tag))
    pub.tags.add(tl)
    pub.save()
    form.save_m2m()
    return HttpResponseRedirect(self.get_success_url())
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top