Reputation:
I'm working on a Django app in which users can ask a Question, but problem is that in case a user types ???
, %%
, etc in the question form & submit it, then slug becomes ''
(slug == ''
) & the form gets saved into database.
class Question(models.Model):
question_text = models.CharField(max_length=250)
slug = models.SlugField(max_length=255, unique=True)
def get_unique_slug(self):
slug = slugify(self.question_text)
unique_slug = slug
num = 1
while Question.objects.filter(slug=unique_slug).exists():
unique_slug = '{}-{}'.format(slug, num)
num += 1
if slug == '':
# what can we do now?
return unique_slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.get_unique_slug()
return super(Question, self).save()
We have to either prevent slug from being a empty string or simply prevent the form from being saved. How can we do that?
Thank You!
Upvotes: 1
Views: 88
Reputation: 8525
In case you want to save something rather than an empty string, this will do the trick.
from django.template.defaultfilters import slugify
import random
import string
def get_unique_slug(instance,new_slug=None,field="question_text"):
''' If you want to target another field, you can change the parameter.
By default we target the "question_text" field '''
def generator(size=10,chars=string.ascii_letters + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
if new_slug:
slug = new_slug
else:
slug = slugify(eval("instance.%s" % field)) # we use `eval` to have the field.
if not slug:
slug = "question{}".format(generator(4))
Klass = instance.__class__
qs_exists = Klass.objects.filter(slug=slug).exists()
if qs_exists:
new_slug = "%s-%s" % (slug,generator(4))
return create_slug(instance,new_slug,field)
return slug
This is you class model. I do not put the 'get_unique_slug' inside the class, in order for you to use it anywhere for other models
class Question(models.Model):
question_text = models.CharField(max_length=250)
slug = models.SlugField(max_length=255, unique=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = get_unique_slug(self,field="question_text") # We target the 'question_text' field, although we can let it empty as it's the default value
return super(Question, self).save()
Upvotes: 0