django admin 不会将对象添加到 Manytomany 字段中

标签 django django-models django-admin

我有一个模型来保存用户帖子:

class Tag(models.Model):
    name = models.CharField(max_length=255, unique=True)

class Post(models.Model):
    user = models.ForeignKey(User)
    body = models.TextField()
    tags = models.ManyToManyField(Tag, blank=True)
    pub_date = models.DateTimeField(default=timezone.now)
    activity = GenericRelation(Activity, related_query_name="posts")

现在,每当我保存新的 Post 对象时,我都想将 Post 对象的正文保存到 Post 对象的标签字段中。我正在使用信号来执行此操作:

@receiver(post_save, sender=Post)
def create(sender, instance, **kwargs):
    if kwargs.get('created', True):
        tag_list = [Tag.objects.create(name=word) for word in instance.body.split()]
        print "from signals!: instance body: %s" % instance.body
        instance.tags.add(*tag_list)

    if not kwargs.get('created', False):
        tag_list = [Tag.objects.create(name=word) for word in instance.body.split()]
        print "already signals!: instance body: %s" % instance.body
        instance.tags.add(*tag_list)

因此,如果我在管理中保存一个新的 Post 对象,它会创建一个新的 Post 对象,还会在 tag_list 中创建标签对象。但是...它不会将tags_list中的标签添加到对象的多对多字段中(即post_object.tags)。

但是,如果我从 shell 创建一个新的 Post 对象,它会创建一个新的 Post 对象,在 tag_list 中创建标签对象,并将标签添加到 post.objects 标签字段中。

我在这里做错了什么?看来问题出在 django admin 中。

最佳答案

经过一番查找,终于解决了我的问题。因此,事实证明,如果您尝试对管理中的 M2M 字段执行某些操作,所做的更改将被clear() 自动删除。

所以,我必须创建一个新的模型管理类:

class PostAdmin(admin.ModelAdmin):
    class Meta:
        model = Post

    def save_model(self, request, obj, form, change):
        print "from save_model"
        obj.save()

    def save_related(self, request, form, formsets, change):
        super(PostAdmin, self).save_related(request, form, formsets, change)
        obj = form.instance
        if obj.body:
            tag_list = [Tag.objects.get_or_create(name=word)[0] for word in obj.body.split() if word.startswith("#")]
            obj.tags.add(*tag_list)
            print("from save_related")
            obj.save()

admin.site.register(Post, PostAdmin)

此外,正如 @Prakhar 指出的那样,我还更改了制作标签列表的方式,从 create() 更改为 get_or_create()注意 get_or_create() 期间的索引 [0],以获取实例而不是创建的

信号.py:

@receiver(post_save, sender=Post)
def create(sender, instance, **kwargs):
    if kwargs.get('created', True):
        tag_list = [Tag.objects.get_or_create(name=word)[0] for word in instance.body.split() if word.startswith("#")]
        print "from signals!: instance body: %s" % instance.body
        instance.tags.add(*tag_list)
    else:
        tag_list = [Tag.objects.get_or_create(name=word)[0] for word in instance.body.split() if word.startswith("#")]
        print "already signals!: instance body: %s" % instance.body
        instance.tags.add(*tag_list)

关于django admin 不会将对象添加到 Manytomany 字段中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41478601/

相关文章:

python - 在 django 迁移期间处理数据?

python - 如何在 Django 中过滤对象以进行计数注释?

Django 作为 S3 代理

python - Django:应用程序标签并不唯一

python - SQLAlchemy 的管理界面?

Django:如何向执行管理操作的管理更改表单页面添加自定义按钮?

javascript - 如何将 onchange js 事件添加到 Django 中的 Select 小部件?

Node.js——一个 Django 风格的管理界面?

python - 管理站点中的默认过滤器

Django 模板 : loop through and print all available properties of an object?