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
を期待していました。
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)
いくつかの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'
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
エラー(予期しない引数)になります。
管理インターフェースを使用してモデルの新しいアイテムを追加する場合、admin.py
でModelAdmin
を設定し、 prepopulated_fields
を使用してスラッグの入力を自動化できます。
class ClientAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
admin.site.register(Client, ClientAdmin)
ここで、ユーザーがname
フィールドの管理フォームに値を入力すると、slug
に正しいスラグ化されたname
が自動的に入力されます。
ほとんどの場合、スラッグは変わらないはずなので、最初の保存時にのみ計算する必要があります。
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()
Adminクラスで prepopulated_fields
を使用します。
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Article, ArticleAdmin)
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()
Django 1.7を使用しています
次のようにモデルにSlugFieldを作成します。
slug = models.SlugField()
次に、admin.py
でprepopulated_fields
を定義します。
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}