web-dev-qa-db-ja.com

ユニークなスラッグを作成する方法Django

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レコード:

  • 郵便番号= "02111"
  • city = "ボストン"
  • statecode = "MA"

サンプルのNeedレコード:

  • 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()関数と、タイトルと都市の間の「_」コネクタを渡す必要があります。誰かがこれを解決し、共有したいと思いますか?

ありがとうございました!

[〜#〜]更新[〜#〜]

私はすでにUUIDFieldにDjango-extensionsを使用しているので、AutoSlugFieldにも使用できるといいですね!

20
mitchf

私はこれを使用します スニペット 一意のスラッグを生成するために、私の典型的な保存方法は以下のようになります

slugはDjango SlugField with blank = Trueですが、saveメソッドでslugを強制します。

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などのスラッグが生成されます。出力は少し異なる場合がありますが、いつでもスニペットを調べてニーズに合わせてカスタマイズできます。

36
Srikanth Chundi

私の小さなコード:

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

あなたがあなたのためにそれをするためにアプリを使うことを考えているなら、ここに1つあります。

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"
5
un33k

これは、タイトルからスラッグを生成する単純な実装であり、他のスニペットに依存しません。

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

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,
    })
1
frostcs

django.utils.textからimportslugify非常に役立ち、非常に明確な概念があります。 Django.utils.textからのインポートslugifyを使用してスラッグを自動生成する方法の1つの例を次に示します。

utils.py

from Django.utils.text import slugify
import random
import string

# Random string generator
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))

# Unique Slug Generator 
def unique_slug_generator(instance, new_slug=None):
    """
    It assumes your instance has a model with a slug field and a title character (char) field.
    """
    if new_slug is not None:
        slug = new_slug  
    else:
        slug = slugify(instance.title)  

    Klass = instance.__class__

    qs_exists = Klass.objects.filter(slug=slug).exists()

    if qs_exists:
        new_slug = "{slug}-{randstr}".format(slug=slug, randstr=random_string_generator(size=4))
        return unique_slug_generator(instance, new_slug=new_slug)
    return slug

models.py

from Django.db.models.signals import pre_save # Signals
# import the unique_slug_generator from .utils.py 
from .utils import unique_slug_generator

class Product(models.Model):
    title  = models.CharField(max_length=120)
    # set blank to True
    slug  = models.SlugField(blank=True, unique=True)

def product_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)


pre_save.connect(product_pre_save_receiver, sender=Product)

Djangoのドキュメントでは、Django.utils.text importslugifyがスラッグを自動的に生成することを説明しています。あなたはより多くの詳細を読むことができます ここ

コードを実装した後、製品を作成するときに、スラッグフィールドを空白のままにすることができます。この場合、製品用に自動生成されたスラッグでさらに取得されます。

1
Manish

こんにちは、この機能を試していただけますか

class Training(models.Model):
    title = models.CharField(max_length=250)
    text = models.TextField()
    created_date = models.DateTimeField(
    auto_now_add=True, editable=False, )
    slug = models.SlugField(unique=True, editable=False, max_length=250)

    def __unicode__(self):
       return self.title

    def save(self, *args, **kwargs):
       self.slug =get_unique_slug(self.id,self.title,Training.objects)
       return super(Training, self).save(*args, **kwargs)

def get_unique_slug(id,title,obj):
    slug = slugify(title.replace('ı', 'i'))
    unique_slug = slug
    counter = 1
    while obj.filter(slug=unique_slug).exists():
       if(obj.filter(slug=unique_slug).values('id')[0]['id']==id):
           break
       unique_slug = '{}-{}'.format(slug, counter)
       counter += 1
    return unique_slug
0
Cihan baş

これを試して、私のために解決し、事前に歓迎します:

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
Kelvin Onkundi