Сигналы Django: не удается использовать для цикла?

#django #django-models #django-signals

#django #django-модели #django-signals

Вопрос:

Когда я удаляю цикл for в сигналах, он работает (создает объект правильно), но когда я использую цикл for, он должен создавать объект для каждого сообщения в объекте Collection, но это не работает. Он даже не создает объект модели Collection_List_Item. Есть ли причина, по которой этот цикл for не работает? Есть ли способ обойти это?

Модели

 class Collection(models.Model):
    posts = models.ManyToManyField(Post, related_name='collection_posts', blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    collection_name = models.CharField(max_length=100)
    collection_description = models.CharField(max_length=1000, blank=True)
    collection_likes = models.ManyToManyField(User, related_name='liked_collections', blank=True)
    collection_image = models.ImageField(upload_to="images/")
    private = models.BooleanField(default=False)
    follows = models.ManyToManyField(User, related_name='collection_follows', blank=True)

    def __str__(self):
        return self.collection_name

class Collection_List_Item(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    collection = models.ForeignKey(Collection, on_delete=models.CASCADE, null=True)
    saved = models.BooleanField(default=False)
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.collection.collection_name
 

сигналы:

 @receiver(post_save, sender=Collection)
def create_collection_list_item(sender, instance, created, **kwargs):
    if created:
        for i in instance.posts.all():
            collection_list_item = Collection_List_Item.objects.create(collection=instance, user=instance.author, post=i)
        
            collection_list_item.save()
 

Ответ №1:

Для ManyToManyField полей вы должны использовать m2m_changed сигнал (Django Docs).

Потому ManyToManyField что сохраняются после сохранения экземпляра, и, следовательно, при всех обновлениях не будет никаких записей ManyToManyField .

 from django.db.models.signals import m2m_changed
from django.db import IntegrityError

@receiver(m2m_changed, sender=Collection.posts.through)
def create_collection_list_item(sender, instance, action, *args, **kwargs):
    if action == "post_add":
        for i in instance.posts.all():
            try:
                collection_list_item = Collection_List_Item.objects.create(collection=instance, user=instance.author, post=i)
            except IntegrityError:
                pass
 

Комментарии:

1. Не могли бы вы добавить какой-нибудь код, чтобы показать мне, как будет выглядеть тело функции, пожалуйста. Потому что у меня проблемы

2. извините, но я также получаю сообщение об ошибке: объект ‘function’ не имеет атрибута ‘connect’

3. @Humza, я отредактировал свой ответ : @receiver(m2m_changed, sender=Collection.posts.through) . Если вы используете create() метод, вам не нужно вызывать save() .

4. @Humza, чтобы создать и сохранить объект за один шаг, используйте метод create(), посмотрите на docs.djangoproject.com/en/dev/topics/db/queries /…