0

I hope you're well. I've two questions for you:

 class Post(models.Model):
        title = models.CharField(max_length=200, unique=True)
        slug = models.SlugField(max_length=200, unique=True)
        url_image = models.URLField(max_length=200, default='SOME STRING')
        author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
        updated_on = models.DateTimeField(auto_now= True)
        name_site = models.CharField(max_length=200, default='NA')
        url_site = models.URLField(max_length=200, default='https://exemple.fr/')
        content = models.TextField()

I. I want my title (unique=False) because I have some similar titles. So is it possible to save my slug (editable=False) with slugify with something like that:

 slug_str = "%s %s" % (self.title, 4 random numbers like that 0476)

If anyone has a better idea, I'm interested in

Thanks a lot :) have a good holidays and take care

Louis
  • 360
  • 2
  • 12

2 Answers2

2

Here are a couple functions that I use. You pass in the model instance and the desired title into unique_slugify which will continue trying to add random strings until one is created that doesn't already exist.

import random
import string

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

def unique_slugify(instance, slug):
    model = instance.__class__
    unique_slug = slug
    while model.objects.filter(slug=unique_slug).exists():
        unique_slug = slug
        unique_slug += random_string_generator(size=4)
    return unique_slug

I usually use it by overriding the model save method.

class YourModel(models.Model):
    slug = models.SlugField(max_length=200, unique=True)
    title = models.CharField(max_length=200)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = unique_slugify(self, slugify(self.title))
        super().save(*args, **kwargs)
bdoubleu
  • 5,568
  • 2
  • 20
  • 53
1

in my opinion, it doesn't make sens two posts may have the same title even with two different slugs, it even confuses readers and even worst it's very bad for SEO. i suggest you to avoid this path and try to review the logic

in models.py

class Post(models.Model):
    title = models.CharField(_('title'), max_length=200,
        unique=True,  # title should be unique
        help_text=_('The title of the entry.')
    )

    slug = models.SlugField(_('slug'), max_length=200,
        unique=True, null=True, blank=True,  
        help_text=_(
            'If blank, the slug will be generated automatically '
            'from the given title.'
        )
    )

[..]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)  # here you don't need to add random numbers since the title is already unque 
        super().save(*args, **kwargs)

in admin.py

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', .. )
    readonly_fields = ('slug', .. )  # Add slug to read_only fields to make it not editable if you want 

cizario
  • 3,995
  • 3
  • 13
  • 27
  • Thanks for your answer but it easier for me to user the same title, as I'm creating a comparator. But thks really appreciate it – Louis Aug 05 '20 at 16:36