Search code examples
djangodjango-modelsdjango-viewsdjango-formsmany-to-many

Can not add ManyToManyFields using froms.py in django


I am trying to add data in a model using django forms but getting

Direct assignment to the forward side of a many-to-many set is prohibited. Use tag.set() instead. Please help me solve this. I am using multiselect field to send data to views.py.

models.py

class Tags(models.Model):
    tag = models.CharField(max_length=100)

    def __str__(self):
        return self.tag

    class Meta:
        verbose_name_plural = 'Tags'

class Post(models.Model):
    ...
    author = models.ForeignKey(User, verbose_name='Author', on_delete=models.CASCADE)
    feature_image = models.ImageField(upload_to='blog/', verbose_name='Add Feature Image')
    tag = models.ManyToManyField(Tags, related_name='post_tags', verbose_name='Add Tags')
    

    def __str__(self):
        return self.title

forms.py

class PostForm(forms.ModelForm):
    ...
    class Meta:
        model = models.Post
        fields = [...]

views

def adminNewPostView(request):
    form = forms.PostForm()
    
    if request.method == 'POST':
        ...
        tags = request.POST.getlist('tagName')
        form = forms.PostForm(request.POST, request.FILES)
        if form.is_valid():
            
            post = form.save(commit=False)
            post.author = request.user
            post.category = cat
            if subcat:
                post.sub_categories = subcat
            if subfil:
                post.filter_option = subfil

            add_tags = models.Tags.objects.filter(tag__in=tags)

            for tl in add_tags:
                post.tag = tl # Getting Error here

            post.save()

         
            return HttpResponseRedirect(reverse('blog_app:index'))

Error

Direct assignment to the forward side of a many-to-many set is prohibited. Use tag.set() instead.


Solution

  • views.py

    def adminNewPostView(request):
        form = forms.PostForm()
        
        if request.method == 'POST':
            ...
            tags = request.POST.getlist('tagName')
            form = forms.PostForm(request.POST, request.FILES)
            if form.is_valid():
                
                post = form.save(commit=False)
                post.author = request.user
                post.category = cat
                if subcat:
                    post.sub_categories = subcat
                if subfil:
                    post.filter_option = subfil
    
                post.save()
                add_tags = models.Tags.objects.filter(tag__in=tags)
    
                for tl in add_tags:
                    post.tag.add(tl) # new
             
                return HttpResponseRedirect(reverse('blog_app:index'))
    

    to learn more about this please refer to https://docs.djangoproject.com/en/dev/ref/models/relations/
    or here https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many/#many-to-many-relationships
    there is also an other way of doing it.like this

    def adminNewPostView(request):
        form = forms.PostForm()
        
        if request.method == 'POST':
            ...
            tags = request.POST.getlist('tagName')
            form = forms.PostForm(request.POST, request.FILES)
            if form.is_valid():
                
                post = form.save(commit=False)
                post.author = request.user
                post.category = cat
                if subcat:
                    post.sub_categories = subcat
                if subfil:
                    post.filter_option = subfil
                post.save()
                add_tags = models.Tags.objects.filter(tag__in=tags)
    
                post.tag.add(*add_tags) # new
    
                
    
             
                return HttpResponseRedirect(reverse('blog_app:index'))