Django模型实例自定义方法

时间:2016-06-18 14:49:28

标签: python django django-models

我正在尝试在Django模型上集成自定义方法

class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    title = models.CharField(max_length=200)
    text = MarkdownField()
    slug = models.SlugField(unique=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    published_date = models.DateTimeField(blank=True, null=True)

    def generate_unique_slug(self):
        slug = self._meta.get_field('slug')
        max_length = slug.max_length
        slug = orig = slugify(self.title)[:max_length]

        for x in itertools.count(1):
            if not Post.objects.filter(slug=slug).exists():
                break

            # Truncate the original slug dynamically. Minus 1 for the hyphen.
            slug = "%s-%d" % (orig[:max_length - len(str(x)) - 1], x)

    def publish(self):
        self.published_date = timezone.now()
        self.generate_unique_slug()
        self.save()

从“发布”调用时,“generate_unique_slug”不起作用。例如,我将从终端

执行此操作
>>> p = Post(title="Title Example", text="Text example")
>>> p.publish()
>>> p.title
'Title Example'
>>> p.published_date
datetime.datetime(2016, 6, 18, 14, 45, 12, 710452, tzinfo=<UTC>)
>>> p.slug
u''

我也试过这个

>>> p.generate_unique_slug()
>>> p.slug
u''

我做错了什么?

3 个答案:

答案 0 :(得分:1)

您没有更新模型的slug。在self.slug = slug

的末尾添加generate_unique_slug
def generate_unique_slug(self):
    # your code
    self.slug = slug

答案 1 :(得分:0)

generate_unique_slug既不会更改任何实例属性也不会返回任何内容。

您应该将slug中的slug = "%s-%d" % (orig[:max_length - len(str(x)) - 1], x)更改为self.slug = ...

答案 2 :(得分:0)

这个答案并没有修复你的代码,但我认为这是一个很好的选择,因为它涵盖了多个案例。

有一个名为uuslug的库正是为此而设计的。可能值得一试。

存储库中的一个示例:

from django.db import models
from uuslug import uuslug

# Override your object's save method with something like this (models.py)
class CoolSlug(models.Model):
    name = models.CharField(max_length=100)
    slug = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.name, instance=self)
        super(CoolSlug, self).save(*args, **kwargs)

name = "john"
c = CoolSlug.objects.create(name=name)
c.save()
print(c.slug) # => "john"

c1 = CoolSlug.objects.create(name=name)
c1.save()
print(c1.slug) # => "john-1"

我也相信您可以将slug = models.CharField(max_length=200)更改为slug = models.SlugField(max_length=200),它仍可以正常使用。

评论后修改:

您可以执行以下操作,而不是覆盖save

from uuslug import slugify

class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    title = models.CharField(max_length=200)
    text = MarkdownField()
    slug = models.SlugField(unique=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    published_date = models.DateTimeField(blank=True, null=True)


    def publish(self):
        self.published_date = timezone.now()
        self.slug = slugify(self.title, max_length=self._meta.get_field('slug'))
        self.save()

这可以解决问题吗?