【问题标题】:Can not add ManyToManyFields using froms.py in django无法在 django 中使用 froms.py 添加 ManyToManyFields
【发布时间】:2021-11-27 06:19:36
【问题描述】:

我正在尝试使用 django 表单在模型中添加数据但得到

禁止直接分配到多对多集合的前端。请改用 tag.set()。 请帮我解决这个问题。我正在使用多选字段将数据发送到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 = [...]

观看次数

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'))

错误

禁止直接分配到多对多集合的前端。请改用 tag.set()。

【问题讨论】:

  • 您的表单是否包含多对多字段?

标签: django django-models django-views django-forms many-to-many


【解决方案1】:

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'))

要了解更多信息,请参考https://docs.djangoproject.com/en/dev/ref/models/relations/
或这里https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many/#many-to-many-relationships
还有另一种方法。像这样

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'))

【讨论】:

  • 试过这个,但得到"<Post: Test Blog>" needs to have a value for field "id" before this many-to-many relationship can be used.
  • @NahidujjamanHridoy 我编辑了我的答案。你应该在 add_tags 变量之前调用 post.save()标签。
  • @NahidujjamanHridoy 并确保将 blank=True 和 null=True 放到模型 Post 的标签字段中。之后运行迁移并迁移它应该可以工作。因为如果你使用 post.save( ) 如果没有标签,它将引发错误,因为据我所知,您需要标签。
【解决方案2】:

一个 Django 表单可以自己处理 ManyToManyFields,但只能使用 .save_m2m().save() 来做到这一点没有使用 commit=False:首先它需要保存 Post 对象因为它需要 Post 对象的主键才能将该对象链接到其他项目。

如果您的PostForm 使用tag 字段:

class PostForm(forms.ModelForm):
    …
    class Meta:
        model = models.Post
        #          ↓ tag field
        fields = ['tag', 'other', 'fields']

然后我们可以让表单为我们完成工作:

从 django.shortcuts 导入重定向

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():
            if subcat:
                form.instance.sub_categories = subcat
            if subfil:
                form.instance.filter_option = subfil
            form.instance.author = request.user
            form.instance.category = cat
            form.save()
            return redirect('blog_app:index')

【讨论】:

  • 没有。我的 PostForm 没有 tag 字段。我使用 select2 multiselect 字段从 html 发送。
  • @NahidujjamanHridoy:您可以在 Django 中使用 select2 小部件:django-select2.readthedocs.io/en/latest
猜你喜欢
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 1970-01-01
  • 2011-12-01
相关资源
最近更新 更多