4👍
This happen because your default value is not function that will be called on each save, it’s rather a constant value generated when your app start
An other option would be moving the logic to save
method of your model:
slug = models.SlugField(
default='',
editable=False,
blank=False
)
...
def save(self, *args, **kwargs):
if not self.default:
self.default = secrets.token_urlsafe(64)
super().save(*args, **kwargs)
1👍
Change your code to:
def get_token_slug():
return secrets.token_urlsafe(64)
…
slug = models.SlugField(
default=get_token_slug,
editable=False,
blank=False,
unique=True, # also add this
)
The problem was that the function call that you give as a default value is computed once and the result is used as a default value in all new instances of this model.
Instead, you should give a callable as a default value, which will then be called when a new instance of the model is created. So just wrap the token_urlsafe
call in a function, and give it as an argument (the function, not a call, so without parentheses ()
)
0👍
In terms of creating a unique slug field when saving an instance of your model, you will need to alter your save method so that it can create a slug which has the next available number appended to the end of your slug. It might look something like the below…
Replace MyModel
and field_you_are_using_to_slugify
as applicable.
def save(self):
if not self.slug.strip():
self.slug = slugify(self.field_you_are_using_to_slugify)
_slug = self.slug
_count = 1
while True:
try:
MyModel.objects.all().exclude(pk=self.pk).get(slug=_slug)
except MultipleObjectsReturned:
pass
except ObjectDoesNotExist:
break
_slug = f"{self.slug}{_count}"
_count += 1
self.slug = _slug
super(MyModel, self).save()
It should be noted however that if you’re after a URL which cannot be interpreted and uses random string generation, then Django provides a UUID field for that purpose. Here is a link to the docs
- [Django]-Add date to url of blog page
- [Django]-Add styling to django Password reset forms
- [Django]-Django Admin Custom Widget for ForeignKey
- [Django]-Django Rest Framework: PUT/POST fails in case of blank optional fields in nested serializer