2017-01-05 4 views
3

У меня есть модель, чтобы сохранить пользовательский пост:Джанго администратор не добавлять объектов в manytomany полей

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, я хотел бы сохранить тело объекта Поста в сообщении объекта, теги. Я делаю это с помощью сигналов:

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

Однако, если я создаю новый объект 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(). Примечание индексирование [0] во время get_or_create(), чтобы получить экземпляр, а не 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)