2009-05-08 2 views
182

Я пытаюсь создать SlugField в Django.Как создать пул в 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' 
>>> 

Я ожидал, что б-б-б-б

+15

Я пришел сюда из «танго с джанго»;) – kmonsoor

ответ

351

Вам нужно будет использовать 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 поле редактируется, который can cause broken links. Это может быть предпочтительным, чтобы генерировать слизняк только один раз, когда вы создаете новый объект:

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) 
+3

застенчивый есть специальный тип модели? почему бы не просто убрать CharFields? – Johnd

+22

SlugFields set db_index = True по умолчанию, а также использовать поле формы по умолчанию, у которого есть регулярное выражение для проверки правильности пули (если оно представлено в ModelForm или в admin). Вы можете делать эти вещи вручную с помощью CharField, если хотите, это просто делает ваш код менее понятным. Кроме того, не забудьте установить параметр ModelAdmin prepopulate_fields, если вы хотите, чтобы JS-авто-prepopulate в admin. –

+4

Как сказал ниже в своем ответе Дингл, вам нужно заменить 'def save (self):' с 'def save (self, * args, ** kwargs):', чтобы избежать ошибок, возникающих при записи чего-либо например 'test.objects.create (q =" blah blah blah ")'. – Liam

27

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

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

admin.site.register(Client, ClientAdmin) 

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

+0

Мои поля 'slug' и' name' имеют переводы. Как я могу это сделать с переводами? Потому что я попытался добавить ''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() 
+8

должен принимать * args и ** kwargs –

57

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

+2

Еще одна очень незначительная вещь, которую нужно добавить к ответу пользователя: я бы сделал последнюю строку 'return super (test, self) .save (* args, ** kwargs)'. Я думаю, что этот метод возвращает «Нет», и я не знаю никаких планов по его изменению, но не вредит возврату того, что делает метод суперкласса, если он изменится когда-нибудь в будущем. –

+0

Пожалуйста, добавьте, что * из django.utils.text import slugify * требуется для этого решения. – Routhinator

+1

@ Routhinator сделал это –

5

Если вы не хотите, чтобы 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

или вы можете использовать editable = False: P – bx2

+0

Документы на [редактируемые] (https://docs.djangoproject.com/en/1.11/ref/models/fields/#editable) – surfer190

4

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

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

admin.site.register(Article, ArticleAdmin) 

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields

+1

Не могли бы вы объяснить? Как администратор влияет на проект? – Bryce

101

Там находится угловой случай с некоторыми 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' 
+4

Это очень важное дополнение, которое должно получить гораздо больше внимания (upvotes), чтобы его заметили! –

+6

utf-8 теперь корректно обрабатывается slugify (в django 1.8.5) –

+0

@ASz Следуя инструкциям, я поддерживал. : D – learner

2

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

Создать SlugField в вашей модели, как это:

slug = models.SlugField() 

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

class ArticleAdmin(admin.ModelAdmin): 
    prepopulated_fields = {"slug": ("title",)} 
Смежные вопросы