Django, m2m_changed в методе save

Django. Есть ли возможность сохранить запись в методе save? То есть, метод save в моделях у меня парсит данные с онлайн кинотеатра. Но у меня есть поле m2m(Жанры) и перед тем, как добавить жанры к записи, запись нужно сохранить, что бы у записи была ID. Я так понимаю, что нужно использовать m2m_changed, но как использовать этот сигнал понять не могу.

class Genre(models.Model):
    title = models.CharField(max_length=30, verbose_name='Жанр', blank=True)


class Trailer(models.Model):
    film_url = models.URLField('Ссылка на фильм')
    genre = models.ManyToManyField(Genre, verbose_name='Жанры', blank=True)

    def save(self, *args, **kwargs):
        source = requests.get(self.film_url).text
        soup = bs4.BeautifulSoup(source, 'html.parser')

        parser_genres = soup.findAll('a', {'class': 'video-genre'})
        for genres in parser_genres:
            genre = Genre.objects.get_or_create(title=genres.text)[0]
            genre.save()
            self.genre.add(genre.id)

Данный код дает ошибку ValueError, говорит что, перед тем как добавить данные в m2m у записи должна быть ID:

"<Trailer: Мстители: Финал>" needs to have a value for field "id" before this many-to-many relationship can be used.


Ответы (1 шт):

Автор решения: 5c0rp

Сперва нужно сохранить Trailer. Уберите ваш код который переопределяет метод save. Далее можно использовать сигнал post_save, а именно:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender= Trailer)
def add_genre(sender, instance, **kwargs):
    source = requests.get(instance.film_url).text
    soup = bs4.BeautifulSoup(source, 'html.parser')

    parser_genres = soup.findAll('a', {'class': 'video-genre'})
    temp = set()
    for genres in parser_genres:
        genre, _ = Genre.objects.get_or_create(title=genres.text)
        temp.add(genre)
    instance.genre.add(*temp)
→ Ссылка