web-dev-qa-db-ja.com

Djangoでスラッグを作成するにはどうすればよいですか?

DjangoでSlugFieldを作成しようとしています。

この単純なモデルを作成しました:

from Django.db import models

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

次にこれを行います:

>>> from mysite.books.models import Test
>>> t=Test(q="aa a a a", s="b b b b")
>>> t.s
'b b b b'
>>> t.save()
>>> t.s
'b b b b'

b-b-b-bを期待していました。

207
Johnd

Slugify関数を使用する必要があります。

>>> from Django.template.defaultfilters import slugify
>>> slugify("b b b b")
u'b-b-b-b'
>>>

slugifyメソッドをオーバーライドすることにより、saveを自動的に呼び出すことができます。

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

    def save(self, *args, **kwargs):
        self.s = slugify(self.q)
        super(Test, self).save(*args, **kwargs)

上記により、qフィールドが編集されたときにURLが変更されることに注意してください。これは リンクの破損を引き起こす可能性があります です。新しいオブジェクトを作成するときに一度だけスラッグを生成することが望ましい場合があります。

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

    def save(self, *args, **kwargs):
        if not self.id:
            # Newly created object, so set slug
            self.s = slugify(self.q)

        super(Test, self).save(*args, **kwargs)
390
Buddy

いくつかのutf-8文字を含むコーナーケースがあります

例:

>>> from Django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u'test-aescon' # there is no "l"

これは nidecode で解決できます

>>> from unidecode import unidecode
>>> from Django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'
111
DooBLER

Thepeerの答えに対する小さな修正:モデルクラスのsave()関数をオーバーライドするには、引数を追加する方が適切です。

from Django.utils.text import slugify

def save(self, *args, **kwargs):
    if not self.id:
        self.s = slugify(self.q)

    super(test, self).save(*args, **kwargs)

それ以外の場合、test.objects.create(q="blah blah blah")force_insertエラー(予期しない引数)になります。

62
Dingle

管理インターフェースを使用してモデルの新しいアイテムを追加する場合、admin.pyModelAdminを設定し、 prepopulated_fields を使用してスラッグの入力を自動化できます。

class ClientAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Client, ClientAdmin)

ここで、ユーザーがnameフィールドの管理フォームに値を入力すると、slugに正しいスラグ化されたnameが自動的に入力されます。

29
henrym

ほとんどの場合、スラッグは変わらないはずなので、最初の保存時にのみ計算する必要があります。

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(editable=False) # hide from admin

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(Test, self).save()
21
thepeer

Adminクラスで prepopulated_fields を使用します。

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

admin.site.register(Article, ArticleAdmin)
6
sergey

Slugfieldを編集不可に設定したくない場合は、NullプロパティとBlankプロパティをFalseに設定する必要があると思います。そうしないと、Adminで保存しようとしたときにエラーが発生します。

したがって、上記の例の変更は次のようになります。

class test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(null=True, blank=True) # Allow blank submission in admin.

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(test, self).save()
5
Streamweaver

Django 1.7を使用しています

次のようにモデルにSlugFieldを作成します。

slug = models.SlugField()

次に、admin.pyprepopulated_fieldsを定義します。

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
3
min2bro