简体   繁体   English

Django 模拟具有独特约束处理的 slug mixin

[英]Django models slug mixin with unique constraint handling

I have three models Book , Part , Chapter , in my models.py that uses the SlugField .我在使用SlugFieldmodels.py中有三个模型BookPartChapter

For the Book class, I have written a slug handler in the custom save method that checks if an object exists with the slug .对于Book class,我在自定义save方法中编写了一个 slug 处理程序,用于检查 object 是否与slug一起存在。 And when it does, it makes it unique by appending a count to it.当它这样做时,它会通过向它附加一个count来使其独一无二。

How do I rewrite the block inside Book 's to SlugMixin so that I can use for the rest of the models?如何将Book中的块重写为SlugMixin以便我可以用于模型的 rest?

models.py

...

class SlugMixin(models.Model):
    slug = models.SlugField(max_length=50, unique=True)

    class Meta:
        abstract = True

class Book(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, unique=True)

    def save(self, *args, **kwargs):
        if not self.pk and not self.slug:
            slug = slugify(self.title, allow_unicode=True)
            slug_exists = True
            counter = 1
            self.slug = slug

            while slug_exists:
                try:
                    slug_exists = Book.objects.get(slug=slug)
                    if slug_exists:
                        slug = self.slug + '_' + str(counter)
                        counter += 1
                except Book.DoesNotExist:
                    self.slug=slug
                    break


class Part(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='parts')
    title = models.CharField(max_length=30)
    slug = models.SlugField(max_length=30, unique=True)


class Chapter(models.Model):
    part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='chapters')
    title = models.CharField(max_length=40)
    slug = models.SlugField(max_length=40, unique=True)

...

How about this这个怎么样

SLUG_LENGTH = 50


def get_unique_slug(model_instance):
    slugify_title = slugify(model_instance.title, allow_unicode=True)
    if len(slugify_title) > SLUG_LENGTH:
        slug = slugify_title[:SLUG_LENGTH]
    else:
        slug = slugify_title
    slug_copy = slug
    num = 1
    while model_instance.__class__.objects.filter(slug=slug).exists():
        number_attached_slug = '{}-{}'.format(slug_copy, num)

        if len(number_attached_slug) > SLUG_LENGTH:
            trimmed_slug = slug_copy[:-(num + 1)]  # adding 1 because there is hyphen in the slug
            slug = '{}-{}'.format(trimmed_slug, num)
        else:
            slug = number_attached_slug
        num += 1

    return slug


class SomeLogicKlass:
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = get_unique_slug(self)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.slug


class Book(SomeLogicKlass, models.Model):
    ...


class Part(SomeLogicKlass, models.Model):
    ...

Note: make sure the value of SLUG_LENGTH is same as the max_length of models.SlugField(...)注意:确保SLUG_LENGTH的值与models.SlugField(...)max_length相同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM