Как создать уникального слизняка в Джанго - PullRequest
19 голосов
/ 28 сентября 2010

Я пытаюсь создать уникальный слаг в Django, чтобы я мог получить доступ к сообщению через URL-адрес: http://www.example.com/buy-a-new-bike_Boston-MA-02111_2

Соответствующие модели:

class ZipCode(models.Model):
    zipcode = models.CharField(max_length=5)
    city = models.CharField(max_length=64)
    statecode = models.CharField(max_length=32)

class Need(models.Model):
    title = models.CharField(max_length=50)
    us_zip = models.CharField(max_length=5)
    slug = ?????

    def get_city():
        zip = ZipCode.objects.get(zipcode=self.us_zip)
        city = "%s, %s %s" % (zip.city, zip.statecode, zip.zipcode)
        return city

Пример записи ZipCode:

  • zipcode = "02111"
  • city = "Бостон"
  • statecode = "MA"

Образец Нужна запись:

  • title = "купить новый велосипед"
  • us_zip = "02111"
  • slug = "buy-a-new-bike_Boston-MA-02111_2" (желательно)

Какие-нибудь советы, как создать этот уникальный слаг? Его состав:

  • Need.title + "_" + Need.get_city () + "_" + необязательное увеличивающееся целое число, чтобы сделать его уникальным. Все пробелы следует заменить на «-».

ПРИМЕЧАНИЕ. Мой желаемый слаг предполагает, что слаг «buy-a-new-bike_Boston-MA-02111» уже существует, к нему добавлен «_2», чтобы сделать его уникальным.

Я пробовал django-расширения, но кажется, что для создания уникального слага может потребоваться только поле или набор полей. Мне нужно передать функцию get_city (), а также соединитель "_" между названием и городом. Кто-нибудь решил это и готов поделиться?

Спасибо!

UPDATE

Я уже использую расширения django для его UUIDField, поэтому было бы неплохо, если бы его можно было использовать для AutoSlugField!

Ответы [ 8 ]

36 голосов
/ 28 сентября 2010

Я использую этот фрагмент для генерации уникального слага, и мой типичный метод сохранения выглядит следующим образом

Слаг будет Django SlugField с пустым = True, но принудительно слаг в методе сохранения.

Типичный метод сохранения для модели Need может выглядеть ниже

def save(self, **kwargs):
    slug_str = "%s %s" % (self.title, self.us_zip) 
    unique_slugify(self, slug_str) 
    super(Need, self).save(**kwargs)

, и это будет генерировать слизняк типа buy-a-new-bike_Boston-MA-02111, buy-a-new-bike_Boston-MA-02111-1 и так далее. Вывод может немного отличаться, но вы всегда можете просмотреть фрагмент и настроить его под свои нужды.

6 голосов
/ 30 июня 2011

Мой маленький код:

def save(self, *args, **kwargs):
    strtime = "".join(str(time()).split("."))
    string = "%s-%s" % (strtime[7:], self.title)
    self.slug = slugify(string)
    super(Need, self).save()
5 голосов
/ 31 мая 2011

Если вы думаете об использовании приложения, чтобы сделать это для вас, вот один из них.

https://github.com/un33k/django-uuslug

UUSlug = (``U``nique + ``U``code Slug)


Unicode Test Example
=====================
from uuslug import uuslug as slugify

s = "This is a test ---"
r = slugify(s)
self.assertEquals(r, "this-is-a-test")

s = 'C\'est déjà l\'été.'
r = slugify(s)
self.assertEquals(r, "c-est-deja-l-ete")

s = 'Nín hǎo. Wǒ shì zhōng guó rén'
r = slugify(s)
self.assertEquals(r, "nin-hao-wo-shi-zhong-guo-ren")

s = '影師嗎'
r = slugify(s)
self.assertEquals(r, "ying-shi-ma")


Uniqueness Test Example
=======================
Override your objects save method with something like this (models.py)

from django.db import models
from uuslug import uuslug as slugify

class CoolSlug(models.Model):
    name = models.CharField(max_length=100)
    slug = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name, instance=self)
        super(CoolSlug, self).save(*args, **kwargs)

Test:
=====

name = "john"
c = CoolSlug.objects.create(name=name)
c.save()
self.assertEquals(c.slug, name) # slug = "john"

c1 = CoolSlug.objects.create(name=name)
c1.save()
self.assertEquals(c1.slug, name+"-1") # slug = "john-1"
2 голосов
/ 26 января 2016

Это простая реализация, которая генерирует слаг из заголовка, он не зависит от других фрагментов:

from django.template.defaultfilters import slugify

class Article(models.Model):
    ...
    def save(self, **kwargs):
        if not self.slug:
            slug = slugify(self.title)
            while True:
                try:
                    article = Article.objects.get(slug=slug)
                    if article == self:
                        self.slug = slug
                        break
                    else:
                        slug = slug + '-'
                except:
                    self.slug = slug
                    break

        super(Article, self).save()
1 голос
/ 27 января 2016

Django предоставляет поле модели SlugField, чтобы вам было проще. Вот пример этого в приложении «блог»

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField(blank=True)

    slug = models.SlugField(unique=True)

    @models.permalink
    def get_absolute_url(self):
        return 'blog:post', (self.slug,)

Обратите внимание, что мы установили unique = True для нашего поля слагов - в этом проекте мы будем искать сообщения по их слагам, поэтому нам нужно убедиться, что они уникальны. Вот как может выглядеть наше приложение views.py для этого:

from .models import Post

def post(request, slug):
    post = get_object_or_404(Post, slug=slug)

    return render(request, 'blog/post.html', {
        'post': post,
    })
0 голосов
/ 20 мая 2019

Попробуйте, сработало для меня, добро пожаловать заранее:

class Parcel(models.Model):
    title = models.CharField(max_length-255)
    slug = models.SlugField(unique=True, max_length=255)
    weight = models.IntegerField()
    description = models.CharField(max_length=255)
    destination = models.CharField(max_length=255)
    origin = models.CharField(max_length=255)

    def __str__(self):
        return self.description

    def save(self, *args, **kwargs):
        if not self.slug:
            t_slug = slugify(self.title)
            startpoint = 1
            unique_slug = t_slug
            while Parcel.objects.filter(slug=unique_slug).exists():
                unique_slug = '{} {}'.format(t_slug, origin)
                origin += 1
            self.slug = unique_slug
        super().save(*args, **kwargs)
0 голосов
/ 09 августа 2018

Привет, ты не мог попробовать эту функцию

0 голосов
/ 29 сентября 2010
class Need(models.Model):
    title = models.CharField(max_length=50)
    us_zip = models.CharField(max_length=5)
    slug = models.SlugField(unique=True)

    def save(self, **kwargs):
        slug_str = "%s %s" % (self.title, self.us_zip) 
        super(Need, self).save()
...