Comment créer une limace unique dans Django
-
26-09-2019 - |
Question
Je suis en train de créer une limace unique dans Django pour que je puisse accéder à un poste via une URL comme ceci: http://www.example.com/buy-a-new- bike_Boston-MA-02111_2
Les modèles concernés:
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
Un échantillon de fiche ZipCode:
- = code postal "02111"
- city = "Boston"
- statecode = "MA"
Un échantillon record besoin:
- title = "acheter un nouveau vélo"
- us_zip = "02111"
- slug = "buy-un-nouveau-bike_Boston-MA-02111_2" (souhaitée)
Des conseils quant à la façon de créer cette limace unique? Sa composition est:
- Need.title + "_" + Need.get_city () + "_" + Un entier incrémentiel en option pour le rendre unique. Tous les espaces doivent être remplacés par « - ».
NOTE: Mon désiré limace ci-dessus suppose que la limace « buy-un-nouveau-bike_Boston-MA-02111 » existe déjà, qui est ce qu'il a le « _2 » qui lui est annexé pour le rendre unique
.J'ai essayé django-extensions, mais il semble que cela ne peut prendre un champ ou tuple des champs pour construire la limace unique. Je dois passer dans la fonction get_city (), ainsi que le connecteur « _ » entre le titre et la ville. Tout le monde a résolu cela et prêts à partager?
Merci!
UPDATE
J'utilise déjà django-extensions pour son UUIDField, donc ce serait bien si elle pourrait aussi être utilisable pour son AutoSlugField!
La solution
J'utilise cette extrait pour générer limace unique et mon look typique méthode de sauvegarde comme ci-dessous
limace sera Django SlugField avec blanc = True mais appliquer limace méthode de sauvegarde.
méthode typique pour le modèle d'économie de besoin peut regarder ci-dessous
def save(self, **kwargs):
slug_str = "%s %s" % (self.title, self.us_zip)
unique_slugify(self, slug_str)
super(Need, self).save(**kwargs)
et cela va générer limace comme un buy-nouveau-bike_Boston-MA-02111, buy-un-nouveau-bike_Boston-MA-02111-1 et ainsi de suite. Ces résultats peuvent être peu différent, mais vous pouvez toujours passer par bout et personnaliser à vos besoins.
Autres conseils
Mon petit code:
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()
Si vous envisagez d'utiliser une application pour le faire pour vous, voici un.
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"
Ceci est une implémentation simple qui génèrent la limace du titre, il ne dépend pas d'autres extraits:
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 fournit un champ de modèle SlugField pour rendre cela plus facile pour vous. Voici un exemple de celui-ci dans une application de « blog »
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,)
Notez que nous avons ensemble unique = True pour notre champ slug - dans ce projet, nous recherchons des postes par leur limace, donc nous devons nous assurer qu'ils sont uniques. Voici ce que le views.py de notre application pourrait ressembler à faire ceci:
from .models import Post
def post(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post.html', {
'post': post,
})
Salut peut vous essayé cette fonction
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
Essayez ceci, a travaillé pour moi, bienvenue à l'avance:
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)
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()