2017-01-05 104 views
3

我有一个模型,以节省用户的后期:Django管理不添加对象到多对多领域

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对象的标签字段。我现在用的信号,这样做:

@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管理员。

+0

两个'if's都指向相同的逻辑:) – ruddra

+2

@ruddra我的问题是完全不同的。 – Robin

+0

对不起我的错误。删除 – ruddra

回答

1

搜索了很多后,我终于解决了我的问题。所以,事实证明,如果您尝试在管理员中对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],以获取实例而不是created

signals.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)