Django에서 슬러그를 어떻게 만듭니 까?


218

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.

답변:


413

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)

4
수줍은 특별한 모델 유형이 있습니까? 왜 CharFields를 슬러그 화하지 않습니까?
Johnd

23
SlugFields는 기본적으로 db_index = True를 설정하고 유효한 슬러그를 요구하기 위해 유효성 검증 정규식이있는 양식 필드를 기본적으로 사용합니다 (ModelForm 또는 관리자에 표시되는 경우). 원하는 경우 CharField를 사용하여 수동으로 이러한 작업을 수행 할 수 있습니다. 코드의 의도를 덜 명확하게 만듭니다. 또한 관리자에서 JS 기반 자동 미리 채우기를 원하는 경우 prepopulate_fields ModelAdmin 설정을 잊지 마십시오.
Carl Meyer

4
Dingle이 그의 답변에서 아래에 말했듯이 def save(self):def save(self, *args, **kwargs):같은 것을 작성할 때 오류가 발생하지 않도록 대체해야합니다 test.objects.create(q="blah blah blah").
Liam

6
이 코드는 저장할 때마다 슬러그를 업데이트합니다. URL이 변경되고 "쿨 URI가 변경되지 않음" w3.org/Provider/Style/URI.html
dzen

18
slugify()django.utils.text.slugify이 (가) 추가 된시기는 명확하지 않은 에서 찾을 수 있습니다 .
mrmagooey 2013

112

utf-8 문자가있는 코너 케이스가 있습니다

예:

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

이것은 유니 코드 로 해결할 수 있습니다

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

7
UTF-8은 지금 (장고 1.8.5에서) slugify 제대로 처리
릭 Westera

@RickWestera가 말했듯이 slugify에 의해 처리되지만, 어떤 이유로 slugify를 사용하지 않으려면 django.utils.encoding에서 iri_to_uri를 확인하십시오. docs.djangoproject.com/en/2.0/ref/unicode/…
Erwol

64

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")A의 발생합니다 force_insert오류 (예기치 않은 인수).


2
동료의 답변에 추가해야 할 또 하나의 사소한 것 : 나는 그 마지막 줄을 만들 것입니다 return super(test, self).save(*args, **kwargs). 이 방법은을 반환한다고 생각 None하지만 변경하려는 계획을 모르지만 수퍼 클래스의 방법이 나중에 언젠가 변경 될 경우 수행하는 것을 반환하는 것은 해가되지 않습니다.
Duncan Parkes

그 추가하십시오 django.utils.text 수입 slugify에서는 이 솔루션이 필요합니다.
Routhinator

1
@Routhinator가 해냈습니다
Jonas Gröger

이것이 여전히 바람직한 방법인지 물어 보는 느낌을주기.
sytech

29

당신이 모델의 새 항목을 추가하는 관리 인터페이스를 사용하는 경우, 당신은을 설정할 수 있습니다 ModelAdmin당신에 admin.py와 활용 prepopulated_fields슬러그의 입력 자동화 :

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

admin.site.register(Client, ClientAdmin)

여기서 사용자가 name필드 의 관리 양식에 값을 slug입력하면 올바른 slugified로 자동으로 채워집니다 name.


slugname필드는 번역이. 번역으로 어떻게 할 수 있습니까? 나는 'slug_en':('name_en',)속성을 내 모델에 존재하지 않는다는 오류 를 추가 하고 얻었습니다.
patricia

22

대부분의 경우 슬러그는 변경되지 않아야하므로 처음 저장할 때만 계산하려고합니다.

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()

6

prepopulated_fields관리자 클래스에서 사용하십시오 .

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

admin.site.register(Article, ArticleAdmin)

1
설명해 주시겠습니까? 관리자는 프로젝트에 어떤 영향을 미칩니 까?
브라이스

5

슬러그 필드를 편집 불가능으로 설정하지 않으려면 Null 및 Blank 속성을 False로 설정하고 싶습니다. 그렇지 않으면 관리자에 저장하려고 할 때 오류가 발생합니다.

따라서 위 예제의 수정 사항은 다음과 같습니다.

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()


4

장고 1.7을 사용하고 있습니다

다음과 같이 모델에 SlugField를 작성하십시오.

slug = models.SlugField()

그런 다음 admin.py정의하십시오 prepopulated_fields.

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

정확히 내가 원하는 것
Nick

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.