verbose_name type slugify django django-models slug

type - Cómo crear un slug único en Django



type models django (7)

Django proporciona un campo de modelo SlugField para que esto sea más fácil para usted. Aquí hay un ejemplo de ello en una aplicación 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,)

Tenga en cuenta que hemos establecido unique = True para nuestro campo de slug: en este proyecto buscaremos publicaciones por su slug, por lo que debemos asegurarnos de que sean únicos. Esto es lo que podría ver el view.py de nuestra aplicación para hacer esto:

from .models import Post def post(request, slug): post = get_object_or_404(Post, slug=slug) return render(request, ''blog/post.html'', { ''post'': post, })

Estoy intentando crear un slug único en Django para poder acceder a una publicación a través de una URL como esta: http://www.example.com/buy-a-new-bike_Boston-MA-02111_2

Los modelos relevantes:

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 ejemplo de registro ZipCode:

  • zipcode = "02111"
  • city ​​= "Boston"
  • statecode = "MA"

Un registro de necesidad de muestra:

  • title = "comprar una bicicleta nueva"
  • us_zip = "02111"
  • slug = "buy-a-new-bike_Boston-MA-02111_2" (deseado)

¿Algún consejo sobre cómo crear esta babosa única? Su composición es:

  • Need.title + "_" + Need.get_city () + "_" + un entero incremental opcional para hacerlo único. Todos los espacios deben ser reemplazados con "-".

NOTA: Mi barra deseada anterior asume que la barra "buy-a-new-bike_Boston-MA-02111" ya existe, que es lo que tiene el "_2" añadido para hacerlo único.

He intentado django-extensions, pero parece que solo puede tomar un campo o una tupla de campos para construir el slug único. Necesito pasar la función get_city () así como el conector "_" entre el título y la ciudad. ¿Alguien resolvió esto y está dispuesto a compartir?

¡Gracias!

ACTUALIZAR

Ya estoy usando django-extensions para su UUIDField, por lo que sería bueno si también pudiera usarse para su AutoSlugField.


Esta es una implementación simple que genera el slug desde el título, no depende de otros fragmentos de código:

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


Hola puedes probar esta función

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


Mi pequeño código:

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 está pensando en utilizar una aplicación para que lo haga por usted, aquí tiene una.

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"


Uso este snippet para generar un slug único y mi método de guardado típico se ve a continuación

slug será Django SlugField con blank = True pero impondrá slug en el método de guardar.

El método típico de guardado para el modelo de Need podría verse abajo.

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

y esto generará una babosa como buy-a-new-bike_Boston-MA-02111, buy-a-new-bike_Boston-MA-02111-1 y así sucesivamente. La salida puede ser un poco diferente, pero siempre puede revisar los fragmentos y personalizarlos según sus necesidades.


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