Reputation: 2393
I am trying to create a url from the title of an object which is given by the user. I figured I could do this in the clean_url
method of the form but it does not seem to work.
def clean_url(self):
url = re.sub(r'\W+', '', str(self.cleaned_data['title']))
return url
How can I add form.url
data to the form before saving?
Model:
class Quiz(models.Model):
title = models.CharField(
verbose_name=_("Title"),
max_length=60,
unique=True,
blank=False)
receiver = models.ManyToManyField(
EmployeeType,
blank=True,
verbose_name='Employee Type',
related_name='quiz_receiver')
description = models.TextField(
verbose_name=_("Description"),
blank=True,
help_text=_("A description of the quiz"))
url = models.SlugField(
max_length=60,
blank=False,
unique=True,
help_text=_("e.g. 'blackjackshuffling'"),
verbose_name=_("User friendly URL"))
Upvotes: 1
Views: 35
Reputation: 477190
The SlugField
is often not specified in a ModelForm
, but constructed by the model. One can make use of the slugify
function [Django-doc] for that:
class Quiz(models.Model):
# …
url = models.SlugField(
max_length=60,
blank=False,
editable=True,
unique=True,
help_text=_("e.g. 'blackjackshuffling'"),
verbose_name=_('User friendly URL')
)
def save(self, *args, **kwargs):
if self.pk is None:
base_url = url = slugify(self.title)
i = 0
while self._meta.model.objects.filter(url=url).exists():
url = f'{base_url}{i}'
i += 1
self.url = url
super().save(*args, **kwargs)
Perhaps it is however more convenient to use the AutoSlugField
[readthedocs] from the django-autoslug
package [readthedocs]. You can install this in your virtual environment with:
pip3 install django-autoslug
In your model you can then specify from what field it should populate and let the AutoSlugField
handle the rest of the logic:
from autoslug import AutoSlugField
class Quiz(models.Model):
# …
url = AutoSlugField(
populate_from='title',
unique=True
)
Upvotes: 2