Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将模型实例保存到多个字段thows AttributeError'Post'对象没有属性'save_m2m',但选中db时,已保存_Python_Django_Django Class Based Views - Fatal编程技术网

Python 将模型实例保存到多个字段thows AttributeError'Post'对象没有属性'save_m2m',但选中db时,已保存

Python 将模型实例保存到多个字段thows AttributeError'Post'对象没有属性'save_m2m',但选中db时,已保存,python,django,django-class-based-views,Python,Django,Django Class Based Views,我的Django 3.1.7博客应用程序有一个带有标记字段的帖子模型,该字段是PostTag模型的多个字段。我希望我的用户能够从一些流行标签中进行选择,或者在我在models.py中创建的新标签字段中添加他们自己的标签。Post模型中不存在新的_标记 我的想法是抓取新标签串,在空格处拆分,然后检查标签是否已经存在——如果确实存在,则创建它。随着新标记被添加到数据库中,这段代码正在工作 当我尝试将这些新标记附加到正在使用表单更新的Post实例时,我的问题就出现了 我已经阅读了大量的SO帖子,并得出

我的Django 3.1.7博客应用程序有一个带有标记字段的帖子模型,该字段是PostTag模型的多个字段。我希望我的用户能够从一些流行标签中进行选择,或者在我在models.py中创建的新标签字段中添加他们自己的标签。Post模型中不存在新的_标记

我的想法是抓取新标签串,在空格处拆分,然后检查标签是否已经存在——如果确实存在,则创建它。随着新标记被添加到数据库中,这段代码正在工作

当我尝试将这些新标记附加到正在使用表单更新的Post实例时,我的问题就出现了

我已经阅读了大量的SO帖子,并得出了下面的视图代码。这会将新标记保存到数据库中的Post实例中。但是,在提交表单时,它仍会抛出AttributeError:“Post”对象没有属性“save_m2m”。但是,如果我删除Post.save_m2m行,则会创建实例,但不会附加到我的Post实例

views.py

类EditPostViewLoginRequiredMixin,UpdateView: 渲染视图以编辑现有帖子 型号=员额 template_name='edit_post.html' 上下文\对象\名称='post' form_class=EditPostForm def表单_validself,表单: post=form.savecommit=False new\u tags=self.request.POST.get'new\u tags' 标签列表=新标签。拆分 对于标签列表中的新标签: post.tags.addPostTag.objects.get\u或\u createname=new\u标记[0] post.save_m2m 返回super.form\u validform def获得成功: 反向返回 “发布详细信息”, kwargs={'pk':self.object.pk,'slug':self.object.slug} 我不明白为什么代码可以工作,但仍然会抛出一个错误。我能做些什么来修复它! 任何关于我做错了什么,或者我可以从这里走到哪里的建议,我们都非常感谢

forms.py

类EditPostForms.ModelForm: 为编辑帖子页面创建表单 ... 新标签=forms.CharField 最大长度=300,要求=False, widget=forms.TextInput 属性={ “模式”:“[a-zA-Z0-9]+”, } 类元: 型号=员额 字段=[ “头衔”, ... “标签”, “新标签” ] 小部件={ “标记”:forms.checkbox选择多个 } models.py

为了不使问题复杂化,我已经从Post模型中删除了额外的字段。如果需要,您可以查看完整的模型

类PostTagmodels。模型: 为帖子创建标签。 名称=型号。CharFieldmax_长度=50 定义自身: 返回self.name 类元: 排序=['name'] 类Postmodels。模型: 创建Post的实例 title=models.CharField 最大长度=70, 唯一=正确, 错误消息={ “唯一”:此文章标题已存在,请选择其他标题。 } tags=models.ManyToManyField PostTag,相关的_name='post_tags',blank=True ... 定义自身: 返回f{self.title} .save_m2m…是表单的一种方法,而不是Post模型,因此您应该使用以下方法调用它:

class EditPostView(LoginRequiredMixin, UpdateView):
    # …

    def form_valid(self, form):
        post = form.save(commit=False)
        new_tags = self.request.POST.get('new_tags')
        tags_list = new_tags.split()

        for new_tag in tags_list:
            post.tags.add(PostTag.objects.get_or_create(name=new_tag)[0])
        form.save_m2m()
        return super().form_valid(form)
从:

为了解决这个问题,每次使用commit=False保存表单时,Django都会向ModelForm子类添加一个save_m2m方法


打电话。请在表格上保存,不要邮寄。

谢谢您的回复。我确实试过了,现在又试了一次。当我测试它时,我没有得到任何错误。它会创建新的PostTag。但是,它不会将它们保存到文章中。@AJG:这可能是因为基础模型save_m2m将清除m2m关系并只插入已添加的关系。@AJG:请参阅编辑。非常感谢!成功了。我真的很感谢你抽出时间来帮忙。一天的大部分时间我都在坚持。
from django.http import HttpResponseRedirect

class EditPostView(LoginRequiredMixin, UpdateView):
    # …

    def form_valid(self, form):
        post = form.save()  save to the database, including the tags
        new_tags = self.request.POST.get('new_tags')
        tags_list = new_tags.split()
        for new_tag in tags_list new_tags.split():
            post.tags.add(PostTag.objects.get_or_create(name=new_tag)[0])
        
        return HttpResponseRedirect(self.get_success_url())