ogreshrek
@ogreshrek
Python + Django

Как генерировать уникальный slug для ManyToMany отношений?

Добрый день! Делаю учебный проект про музыкантов и их релизы.

Мой вопрос в следующем:
Я имею модель музыканта и релиза. Релиз может иметь несколько музыкантов.
Я хочу, чтобы у каждого релиза был уникальный slug, состоящий из {автор}-{название релиза}, если автор один и {автор}-{автор}-...-{название релиза}, если авторов несколько.

Вот мои модели:
class Musician(models.Model):
    name = models.CharField(verbose_name='Название', 
        blank=False, unique=True
        )

    slug_name = models.SlugField(verbose_name='Слаг', 
        blank=True, unique=True)

    def slugify_name(self):
        """
        Обновляет слаг при сохранении.
        """
        self.slug_name = slugify(self.name)

    def save(self, *args, **kwargs):
        self.slugify_name()
        super().save(*args, **kwargs)

class Release(models.Model):
    author = models.ManyToManyField(
        Musician, 
        verbose_name='Автор', related_name='releases')

    name = models.CharField(
        verbose_name='Название', blank=False,
        )

    slug_name = models.SlugField(verbose_name='Слаг', 
        blank=True, unique=True)

    def get_author_slug(self):
        """
        Возвращает всех авторов релиза в формате '{автор}-{автор}-...'
        """
        if len(self.author.all()) == 1:
            return slugify(''.join([str(a) for a in self.author.all()]))
        else:
            return slugify('-'.join([str(a) for a in self.author.all()]))

    def get_slug(self):
        """
        Генерирует слаг в формате {автор}-{автор}-...-{название релиза}
        """
        author = self.get_author_slug()
        name = self.get_name_slug()
        self.slug_name = slugify(author + '-' + name)

    def slugify_name(self):
        """
        Генерирует слаг в формате {название релиза}-{id}
        """
        self.slug_name = slugify('{}-{}'.format(self.name, self.id))

def create_slug_name(sender, instance, created, **kwargs):
    if created:
        instance.slugify_name()
        instance.save()

post_save.connect(create_slug_name, sender=Release)

На данный момент, что я имею.
У меня есть методы в модели релиза:
get_author_slug(), get_slug(), а также сигнал create_slug_name

Метод get_slug() создает весь уникальный slug, как я и хочу. Проблема в том, что этот метод можно применить только в shell, после создания релиза с уникальным слагом.
Сигнал генерирует слаг в формате {название релиза}-{id}. Уникально - да, но не то, что нужно.

Что можно придумать, чтобы слаг создавался каждый раз при создании/изменении имени релиза.
  • Вопрос задан
  • 614 просмотров
Решения вопроса 1
@MAGistr_MTM
Учусь программировать
Сигнал нужно вызывать на m2m-changed
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы