Как добавить индекс в мой слаг, если он уже существует в базе данных? - PullRequest
0 голосов

Когда я создаю новое сообщение, мне нужно сделать следующее:

1. Generate slug from self.title with slugify
2. Check if this slug does not exists we save post with self.slug
3. If this slug already exists we save post with self.slug + '-' + count index

Я нашел работающее решение, но я новичок в Django, поэтому я хочу спросить вас, это оптимальное решение?

#models.py

from django.db import models
from django.shortcuts import reverse
from django.utils.text import slugify
from django.db.models.signals import post_save
from django.dispatch import receiver

class Post(models.Model):
    title = models.CharField(max_length=150, db_index=True)
    slug = models.SlugField(max_length=150, blank=True, unique=True)

    def get_absolute_url(self):
        return reverse('post_detail_url', kwargs={'slug': self.slug})

@receiver(post_save, sender=Post)
def set_slug(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = slugify(instance.title)
        while Post.objects.filter(slug__startswith=instance.slug).exists():
            instance.slug += '-' + str(Post.objects.filter(slug__startswith=instance.slug).count())
        instance.save()

1 Ответ

0 голосов
/ 25 мая 2019

A сигнал предварительного сохранения - лучший способ справиться с этим. Каждый раз, когда экземпляр собирается сохранить, сигнал срабатывает и запускает некоторую логику. В этом случае перед заполнением будет заполнено поле slug.

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

# you other stuff goes here

@receiver(pre_save, sender=MyModel)
def set_slug(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)

И это все!

Если ваши сигналы не связаны между приложениями, вы можете разместить их на models.py. Но если вы используете его для подключения разных приложений или общего сигнала к нескольким приложениям, у вас может быть отдельный файл для размещения.

Просто примечание: видите этот sender=MyModel кусок? Это связывает сигнал с конкретной моделью. Если у вас есть много моделей, которые будут использовать слагов, вы можете просто удалить их, чтобы сделать хук предварительного сохранения доступным для нескольких моделей.

...