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レコード:
サンプルのNeedレコード:
このユニークなスラッグを作成する方法に関するヒントはありますか?その構成は次のとおりです。
注:上記の希望するスラッグは、スラッグ「buy-a-new-bike_Boston-MA-02111」がすでに存在していることを前提としています。これは、一意にするために「_2」が追加されているものです。
Django拡張機能を試しましたが、一意のスラッグを作成するには、フィールドまたはフィールドのタプルしか使用できないようです。 get_city()関数と、タイトルと都市の間の「_」コネクタを渡す必要があります。誰かがこれを解決し、共有したいと思いますか?
ありがとうございました!
[〜#〜]更新[〜#〜]
私はすでにUUIDFieldにDjango-extensionsを使用しているので、AutoSlugFieldにも使用できるといいですね!
私はこれを使用します スニペット 一意のスラッグを生成するために、私の典型的な保存方法は以下のようになります
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などのスラッグが生成されます。出力は少し異なる場合がありますが、いつでもスニペットを調べてニーズに合わせてカスタマイズできます。
私の小さなコード:
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()
あなたがあなたのためにそれをするためにアプリを使うことを考えているなら、ここに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"
これは、タイトルからスラッグを生成する単純な実装であり、他のスニペットに依存しません。
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()
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,
})
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がスラッグを自動的に生成することを説明しています。あなたはより多くの詳細を読むことができます ここ
コードを実装した後、製品を作成するときに、スラッグフィールドを空白のままにすることができます。この場合、製品用に自動生成されたスラッグでさらに取得されます。
こんにちは、この機能を試していただけますか
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
これを試して、私のために解決し、事前に歓迎します:
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)