Как мне создать слизняк в Django? - PullRequest
206 голосов
/ 08 мая 2009

Я пытаюсь создать SlugField в Django.

Я создал эту простую модель:

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.

Ответы [ 9 ]

386 голосов
/ 08 мая 2009

Вам нужно будет использовать функцию 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)

Имейте в виду, что приведенное выше приведёт к изменению вашего URL при редактировании поля q, что может привести к неработающим ссылкам . Может быть предпочтительнее генерировать слаг только один раз при создании нового объекта:

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)
110 голосов
/ 31 августа 2012

Угловой регистр с некоторыми символами utf-8

Пример:

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

Это можно решить с помощью Unidecode

>>> from unidecode import unidecode
>>> from django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'
62 голосов
/ 26 сентября 2009

Небольшая поправка к ответу 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 (неожиданный аргумент).

29 голосов
/ 09 мая 2009

Если вы используете интерфейс администратора для добавления новых элементов вашей модели, вы можете установить ModelAdmin в вашем admin.py и использовать prepopulated_fields для автоматизации ввода слага:

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

admin.site.register(Client, ClientAdmin)

Здесь, когда пользователь вводит значение в форму администратора для поля name, slug будет автоматически заполняться правильным slugified name.

21 голосов
/ 09 мая 2009

В большинстве случаев слаг не должен меняться, так что вы действительно хотите рассчитать его только при первом сохранении:

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 голосов
/ 04 февраля 2011

Используйте prepopulated_fields в вашем классе администратора:

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

admin.site.register(Article, ArticleAdmin)
5 голосов
/ 14 декабря 2010

Если вы не хотите устанавливать для поля слагов значение «Не быть редактируемым», то, я думаю, вы захотите установить для свойств «Пустой» и «Пустой» значение «Ложь». В противном случае вы получите ошибку при попытке сохранить в 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()
3 голосов
/ 15 февраля 2015

Я использую Django 1.7

Создайте SlugField в своей модели следующим образом:

slug = models.SlugField()

Затем в admin.py определить prepopulated_fields;

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
0 голосов
/ 14 августа 2018

Вы можете посмотреть документы для SlugField, чтобы узнать больше об этом более наглядно.

...