如何在Django中创建一个独特的slug

mit*_*chf 19 django django-models slug

我正在尝试在Django中创建一个独特的slug,以便我可以通过这样的URL访问帖子:http: //www.example.com/buy-a-new-bike_Boston-MA-02111_2

相关型号:

class ZipCode(models.Model):
    zipcode = models.CharField(max_length=5)
    city = models.CharField(max_length=64)
    statecode = models.CharField(max_length=32)

class Need(models.Model):
    title = models.CharField(max_length=50)
    us_zip = models.CharField(max_length=5)
    slug = ?????

    def get_city():
        zip = ZipCode.objects.get(zipcode=self.us_zip)
        city = "%s, %s %s" % (zip.city, zip.statecode, zip.zipcode)
        return city
Run Code Online (Sandbox Code Playgroud)

ZipCode记录示例:

  • zipcode ="02111"
  • city ="波士顿"
  • statecode ="MA"

样本需求记录:

  • title ="买一辆新自行车"
  • us_zip ="02111"
  • slug ="buy-a-new-bike_Boston-MA-02111_2"(需要)

有关如何创建这个独特的slug的任何提示?它的组成是:

  • Need.title +"_"+ Need.get_city()+"_"+一个可选的递增整数,使其唯一.所有空格都应替换为" - ".

注意:上面我想要的slug假定slug"buy-a-new-bike_Boston-MA-02111"已经存在,这就是它附加了"_2"以使其独一无二.

我尝试过django-extensions,但它似乎只需要一个字段或字段来构造独特的slug.我需要传入get_city()函数以及标题和城市之间的"_"连接符.有人解决了这个并愿意分享?

谢谢!

UPDATE

我已经在其UUIDField中使用了django-extensions,所以如果它也可用于其AutoSlugField会很好!

Sri*_*ndi 36

我使用这个片段生成独特的slug,我的典型保存方法如下所示

slug将是Django SlugField,其中为blank = True,但在save方法中强制执行slug.

Need model的典型保存方法如下所示

def save(self, **kwargs):
    slug_str = "%s %s" % (self.title, self.us_zip) 
    unique_slugify(self, slug_str) 
    super(Need, self).save(**kwargs)
Run Code Online (Sandbox Code Playgroud)

这将产生像买一辆新自行车_Boston-MA-02111,买一辆新自行车_Boston-MA-02111-1等等.输出可能会略有不同,但您可以随时通过代码片段并根据您的需求进行自定义.

  • 我会避免在 Django 中使用信号。我发现它们很难调试,因为您通常将信号代码移至单独的文件中。人们很容易忘记它。使用信号的时间是当您想要对实例进行修改时,并且该实例并不总是相同的模型。 (2认同)

bdo*_*leu 7

这是我使用的几个函数。您传入模型实例和所需的标题,unique_slugify如果不存在,则会将 slug 添加到其中,否则它将继续尝试附加 4 位随机字符串,直到找到唯一的字符串。

import string
from django.utils.crypto import get_random_string

def unique_slugify(instance, slug):
    model = instance.__class__
    unique_slug = slug
    while model.objects.filter(slug=unique_slug).exists():
        unique_slug = slug + get_random_string(length=4)
    return unique_slug
Run Code Online (Sandbox Code Playgroud)

我通常通过重写模型save方法来使用它。

class YourModel(models.Model):
    slug = models.SlugField()
    title = models.CharField()

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = unique_slugify(self, slugify(self.title))
        super().save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)


Nip*_*ips 6

我的小代码:

def save(self, *args, **kwargs):
    strtime = "".join(str(time()).split("."))
    string = "%s-%s" % (strtime[7:], self.title)
    self.slug = slugify(string)
    super(Need, self).save()
Run Code Online (Sandbox Code Playgroud)


un3*_*33k 5

如果您正在考虑使用应用程序为您做这件事,这里就是一个。

https://github.com/un33k/django-uuslug

UUSlug = (``U``nique + ``U``code Slug)


Unicode Test Example
=====================
from uuslug import uuslug as slugify

s = "This is a test ---"
r = slugify(s)
self.assertEquals(r, "this-is-a-test")

s = 'C\'est déjà l\'été.'
r = slugify(s)
self.assertEquals(r, "c-est-deja-l-ete")

s = 'Nín h?o. W? shì zh?ng guó rén'
r = slugify(s)
self.assertEquals(r, "nin-hao-wo-shi-zhong-guo-ren")

s = '???'
r = slugify(s)
self.assertEquals(r, "ying-shi-ma")


Uniqueness Test Example
=======================
Override your objects save method with something like this (models.py)

from django.db import models
from uuslug import uuslug as slugify

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 = slugify(self.name, instance=self)
        super(CoolSlug, self).save(*args, **kwargs)

Test:
=====

name = "john"
c = CoolSlug.objects.create(name=name)
c.save()
self.assertEquals(c.slug, name) # slug = "john"

c1 = CoolSlug.objects.create(name=name)
c1.save()
self.assertEquals(c1.slug, name+"-1") # slug = "john-1"
Run Code Online (Sandbox Code Playgroud)

  • 线程安全在这里不是问题。我的意思是不同应用程序实例之间的并发性,它们两者可能同时生成相同的段(例如'john-1'),并且当他们尝试保存模型时,它们会出现完整性错误。 (2认同)