Auto Generated Slugs in Django Admin - django

I have an app that will one day allow front-end crud, which will create the slug with slugify. Right now though, all the object creation is being done in the admin area and I was wondering if there is a way to auto generate slugs while creating and saving an object from within admin?
Here is the method for slugify for the front-end; not sure if its even relevant. Thank you.
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = Veteran.objects.filter(slug=slug).order_by('-id')
exists = qs.exists()
if exists:
new_slug = '%s-%s' % (slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug

Having just used this on another answer, I have exactly the right code in my clipboard. I do exactly this for one of my models:
from django.utils.text import slugify
class Event(models.Model):
date = models.DateField()
location_title = models.TextField()
location_code = models.TextField(blank=True, null=True)
picture_url = models.URLField(blank=True, null=True, max_length=250)
event_url = models.SlugField(unique=True, max_length=250)
def __str__(self):
return self.event_url + " " + str(self.date)
def save(self, *args, **kwargs):
self.event_url = slugify(self.location_title+str(self.date))
super(Event, self).save(*args, **kwargs)

Above solutions break validation in the Django Admin interface. I suggest:
from django import forms
from django.http.request import QueryDict
from django.utils.text import slugify
from .models import Article
class ArticleForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ArticleForm, self).__init__(*args, **kwargs)
# Ensure that data is a regular Python dictionary so we can
# modify it later.
if isinstance(self.data, QueryDict):
self.data = self.data.copy()
# We assume here that the slug is only generated once, when
# saving the object. Since they are used in URLs they should
# not change when valid.
if not self.instance.pk and self.data.get('title'):
self.data['slug'] = slugify(self.data['title'])
class Meta:
model = Article
exclude = []

Related

One view for two models with redirect

I have Django app with the following model:
class Author(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
This is now using simple generic view:
class AuthorDetail(DetailView):
model = Author
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# some additional context thingies
return context
and with the following URL configuration:
path('author/<slug:slug>/', AuthorDetail.as_view(), name='author-detail'),
Now I want to introduce simple aliases for authors, so for example instead of /author/william-shakespeare I can reach the page also as /author/ws or /author/my-favourite-author.
I came up with this idea (I know that destination could be key to Author, but that (I think) would not change much in the case):
class AuthorAlias(models.Model):
slug = models.SlugField(max_length=200, unique=True)
destination = models.CharField(max_length=200)
So to achieve the redirect I came up with the following in the view:
def get(self, request, **kwargs):
slug = kwargs['slug']
try:
self.object = self.get_object()
except Http404:
self.object = get_object_or_404(AuthorAlias, slug=slug)
return redirect(reverse('author-detail', args=[self.object.destination]))
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
Everything seems to be working fine, but I was wondering it there is a better approach and if this approach can cause any issues I'm not seeing?
The problem here is that destination does not per se refer to a real author. You can alter this by using a ForeignKey instead:
class AuthorAlias(models.Model):
destination = models.ForeignKey('Author', on_delete=models.CASCADE)>
slug = models.SlugField(max_length=200, unique=True)
In the Author class it might be better to implement the get_absolute_url(…) method [Django-doc] to define a canonical url:
from django.urls import reverse
class Author(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
def get_absolute_url(self):
return reverse('author-detail', kwargs={'slug': self.slug})
Now we can implement the DetailView with:
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
class AuthorDetail(DetailView):
model = Author
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# some additional context thingies
return context
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except Http404:
return redirect(get_object_or_404(
Author,
authoralias__slug=self.kwargs['slug']
))
context = self.get_context_data(object=self.object)
return self.render_to_response(context)

Django-taggit how to modify to have same tag added by different user

I am trying to modify django-taggit to allow the same tag to be added by separate teams.
I have modified django-taggit Model so that it has user and team_id values added when a user adds a new tag to taggig_tag table. This also adds user and team_id values to taggit_taggeditems table.
The goal is to allow teams to edit or delete their own tags and that should not affect other teams, so different teams need to have their own separate sets of tags.
In my modified scenario, the tag name and team_id constitute a distinct tag. I expect i can test team_id or concatenate it to the tag name before django-taggit tests for distinct tags. But do not see where django-taggit does that.
Question: Where in the django-taggit code does it look for duplicate tag values?
`apps.py`
`forms.py`
`managers.py`
`models.py`
`utils.py`
`views.py`
My modified django-taggit Model code is below.
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import IntegrityError, models, router, transaction
from django.utils.text import slugify
from django.utils.translation import gettext, gettext_lazy as _
from django.conf import settings
### MODIFICATION: added django CRUM to get request user
from crum import get_current_user
try:
from unidecode import unidecode
except ImportError:
def unidecode(tag):
return tag
class TagBase(models.Model):
### MODIFICATION: added team and user to model, removed unique=True
name = models.CharField(verbose_name=_("Name"), max_length=100)
slug = models.SlugField(verbose_name=_("Slug"), max_length=100)
team_id = models.CharField(max_length=10, blank=False, null=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
def __gt__(self, other):
return self.name.lower() > other.name.lower()
def __lt__(self, other):
return self.name.lower() < other.name.lower()
class Meta:
abstract = True
def save(self, *args, **kwargs):
### MODIFICATION: added team and user to taggit_taggeditem model
### get request user with django CRUM get_current_user()
self.user = get_current_user()
self.team_id = get_current_user().team_id
if self._state.adding and not self.slug:
self.slug = self.slugify(self.name)
using = kwargs.get("using") or router.db_for_write(
type(self), instance=self
)
# Make sure we write to the same db for all attempted writes,
# with a multi-master setup, theoretically we could try to
# write and rollback on different DBs
kwargs["using"] = using
# Be oportunistic and try to save the tag, this should work for
# most cases ;)
### MODIFICATION: remove IntegrityError try/except for unique
which is removed
#try:
with transaction.atomic(using=using):
res = super().save(*args, **kwargs)
return res
#except IntegrityError:
# pass
### MODIFICATION: remove slugs create as no longer checking for
duplicate slugs
# Now try to find existing slugs with similar names
#slugs = set(
# self.__class__._default_manager.filter(
# slug__startswith=self.slug
# ).values_list("slug", flat=True)
#)
i = 1
#while True:
# slug = self.slugify(self.name, i)
# if slug not in slugs:
# self.slug = slug
# # We purposely ignore concurrecny issues here for now.
# # (That is, till we found a nice solution...)
# return super().save(*args, **kwargs)
# i += 1
while True:
slug = self.slugify(self.name, i)
#if slug not in slugs:
self.slug = slug
# We purposely ignore concurrecny issues here for now.
# (That is, till we found a nice solution...)
return super().save(*args, **kwargs)
i += 1
else:
return super().save(*args, **kwargs)
def slugify(self, tag, i=None):
slug = slugify(unidecode(tag))
if i is not None:
slug += "_%d" % i
return slug
class Tag(TagBase):
class Meta:
verbose_name = _("Tag")
verbose_name_plural = _("Tags")
app_label = "taggit"
class ItemBase(models.Model):
def __str__(self):
return gettext("%(object)s tagged with %(tag)s") % {
"object": self.content_object,
"tag": self.tag,
}
class Meta:
abstract = True
#classmethod
def tag_model(cls):
field = cls._meta.get_field("tag")
return field.remote_field.model
#classmethod
def tag_relname(cls):
field = cls._meta.get_field("tag")
return field.remote_field.related_name
#classmethod
def lookup_kwargs(cls, instance):
return {"content_object": instance}
class TaggedItemBase(ItemBase):
tag = models.ForeignKey(
Tag, related_name="%(app_label)s_%(class)s_items",
on_delete=models.CASCADE
)
class Meta:
abstract = True
#classmethod
def tags_for(cls, model, instance=None, **extra_filters):
kwargs = extra_filters or {}
if instance is not None:
kwargs.update({"%s__content_object" % cls.tag_relname():
instance})
return cls.tag_model().objects.filter(**kwargs)
kwargs.update({"%s__content_object__isnull" % cls.tag_relname():
False})
return cls.tag_model().objects.filter(**kwargs).distinct()
class CommonGenericTaggedItemBase(ItemBase):
content_type = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
verbose_name=_("Content type"),
related_name="%(app_label)s_%(class)s_tagged_items",
)
content_object = GenericForeignKey()
### MODIFICATION: added team and user to taggit_taggeditem model
team_id = models.CharField(max_length=10, blank=False, null=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
on_delete=models.DO_NOTHING)
class Meta:
abstract = True
#classmethod
def lookup_kwargs(cls, instance):
return {
"object_id": instance.pk,
"content_type": ContentType.objects.get_for_model(instance),
### MODIFICATION: added team and user to taggit_taggeditem model
"user": get_current_user(),
"team_id": get_current_user().team_id,
}
#classmethod
def tags_for(cls, model, instance=None, **extra_filters):
tag_relname = cls.tag_relname()
kwargs = {
"%s__content_type__app_label" % tag_relname:
model._meta.app_label,
"%s__content_type__model" % tag_relname: model._meta.model_name,
}
if instance is not None:
kwargs["%s__object_id" % tag_relname] = instance.pk
if extra_filters:
kwargs.update(extra_filters)
return cls.tag_model().objects.filter(**kwargs).distinct()
class GenericTaggedItemBase(CommonGenericTaggedItemBase):
object_id = models.IntegerField(verbose_name=_("Object id"),
db_index=True)
class Meta:
abstract = True
class GenericUUIDTaggedItemBase(CommonGenericTaggedItemBase):
object_id = models.UUIDField(verbose_name=_("Object id"), db_index=True)
class Meta:
abstract = True
class TaggedItem(GenericTaggedItemBase, TaggedItemBase):
class Meta:
verbose_name = _("Tagged Item")
verbose_name_plural = _("Tagged Items")
app_label = "taggit"
### MODIFICATION: added team_id and user to taggit_taggeditems table
constraints
index_together = [["content_type", "object_id", "team_id", "user"]]
unique_together = [["content_type", "object_id", "tag", "team_id",
"user"]]

Django set slug in view

can anyone tell me how to set a slug in a view?
I pretend to use name as slug,
def editar_cliente(request, pk):
detail = database.objects.get(pk=pk)
name = detail.name
company = detail.company
pk = detalle.pk
return render(request, 'edit_client.html'company': company, 'pk':pk})
I would create slug in the model's save method:
from django.utils.text import slugify
class Client(models.Model):
name = models.CharField(max_length=30)
slug = models.SlugField(editable=False) # hide from admin
def save(self):
if not self.pk:
self.s = slugify(self.name)
super(Client, self).save()
But you could use the same approach to set it in view as well:
from django.utils.text import slugify
def editar_cliente(request, pk):
detail = database.objects.get(pk=pk)
name = detail.name
company = detail.company
pk = detalle.pk
slug = slugify(name)
return render(request, 'edit_client.html'company': company, 'pk':pk})
Hope it helps.

dynamic FilePathField question

I have a model where the location of pdf directory I'm pointing to with my FilePathField is based on the "client" and "job_number" fields.
class CCEntry(models.Model):
client = models.CharField(default="C_Comm", max_length=64)
job_number = models.CharField(max_length=30, unique=False, blank=False, null=False)
filename = models.CharField(max_length=64, unique=False, blank=True, null=True)
pdf = models.FilePathField(path="site_media/jobs/%s %s", match=".*\.pdf$", recursive=True
#property
def pdf(self):
return "site_media/jobs/%s %s" % (self.client, self.job_number)
def __unicode__ (self):
return u'%s %s' % (self.client, self.filename)
class Admin:
pass
I've tried to pass the client and job_number data to the pdf field dynamically by using a #property method on the model class, but either my approach or my syntax is fualty because the entire pdf field disappears in the admin. Any pointers on what I'm doing wrong?
Based on your subsequent post on similar functionality in the FileField (see last link below)
And my inability to get any of the above to work, I'm gonna hazard a guess that it's not yet possible for the FilePathField field type.
I know that passing a callable works for most fields' 'default' parameters...
https://docs.djangoproject.com/en/dev/ref/models/fields/#default
... as it appears to work for the upload_to param of FieldField
(eg https://stackoverflow.com/questions/10643889/dynamic-upload-field-arguments/ ) andImageField` (eg Django - passing extra arguments into upload_to callable function )
Anyone interested in extending FilePathField to include this feature?
Anyone interested in extending FilePathField to include this feature?
I'd love to see this extension!
Just for the record, this is the solution that worked for me (django 1.3):
# models.py
class Analysis(models.Model):
run = models.ForeignKey(SampleRun)
# Directory name depends on the foreign key
# (directory was created outside Django and gets filled by a script)
bam_file = models.FilePathField(max_length=500, blank=True, null=True)
# admin.py
class CustomAnalysisModelForm(forms.ModelForm):
class Meta:
model = Analysis
def __init__(self, *args, **kwargs):
super(CustomAnalysisModelForm, self).__init__(*args, **kwargs)
# This is an update
if self.instance.id:
# set dynamic path
mypath = settings.DATA_PATH + self.instance.run.sample.name
self.fields['bam_file'] = forms.FilePathField(path=mypath, match=".*bam$", recursive=True)
class AnalysisAdmin(admin.ModelAdmin):
form = CustomAnalysisModelForm
Hope this helps somebody out there.
try to set the path value as callable function
def get_path(instance, filename):
return "site_media/jobs/%s_%s/%s" % (instance.client, instance.job_number, filename)
class CCEntry(models.Model):
....
pdf = models.FilePathField(path=get_path, match=".*\.pdf$", recursive=True)
but I'm not sure if this works, I didn't test it.
Added an implementation of this based on Django v1.9 FilePathField implementation:
from django.db.models import FilePathField
class DynamicFilePathField(FilePathField):
def __init__(self, verbose_name=None, name=None, path='', match=None,
recursive=False, allow_files=True, allow_folders=False, **kwargs):
self.path, self.match, self.recursive = path, match, recursive
if callable(self.path):
self.pathfunc, self.path = self.path, self.path()
self.allow_files, self.allow_folders = allow_files, allow_folders
kwargs['max_length'] = kwargs.get('max_length', 100)
super(FilePathField, self).__init__(verbose_name, name, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super(FilePathField, self).deconstruct()
if hasattr(self, "pathfunc"):
kwargs['path'] = self.pathfunc
return name, path, args, kwargs
And example use:
import os
from django.db import models
def get_data_path():
return os.path.abspath(os.path.join(os.path.dirname(__file__), 'data'))
class GenomeAssembly(models.Model):
name = models.CharField(
unique=True,
max_length=32)
chromosome_size_file = DynamicFilePathField(
unique=True,
max_length=128,
path=get_data_path,
recursive=False)

How to create a unique slug in Django

I am trying to create a unique slug in Django so that I can access a post via a url like this:
http://www.example.com/buy-a-new-bike_Boston-MA-02111_2
The relevant models:
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
A sample ZipCode record:
zipcode = "02111"
city = "Boston"
statecode = "MA"
A sample Need record:
title = "buy a new bike"
us_zip = "02111"
slug = "buy-a-new-bike_Boston-MA-02111_2" (desired)
Any tips as to how to create this unique slug? Its composition is:
Need.title + "_" + Need.get_city() + "_" + an optional incrementing integer to make it unique. All spaces should be replaced with "-".
NOTE: My desired slug above assumes that the slug "buy-a-new-bike_Boston-MA-02111" already exists, which is what it has the "_2" appended to it to make it unique.
I've tried django-extensions, but it seems that it can only take a field or tuple of fields to construct the unique slug. I need to pass in the get_city() function as well as the "_" connector between the title and city. Anyone solved this and willing to share?
Thank you!
UPDATE
I'm already using django-extensions for its UUIDField, so it would be nice if it could also be usable for its AutoSlugField!
I use this snippet for generating unique slug and my typical save method look like below
slug will be Django SlugField with blank=True but enforce slug in save method.
typical save method for Need model might look below
def save(self, **kwargs):
slug_str = "%s %s" % (self.title, self.us_zip)
unique_slugify(self, slug_str)
super(Need, self).save(**kwargs)
and this will generate slug like buy-a-new-bike_Boston-MA-02111 , buy-a-new-bike_Boston-MA-02111-1 and so on. Output might be little different but you can always go through snippet and customize to your needs.
My little code:
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()
If you are thinking of using an app to do it for you, here is one.
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"
Here are a couple functions that I use. You pass in the model instance and the desired title into unique_slugify which will add the slug if it doesn't exist, otherwise it will continue trying to append a 4 digit random string until it finds a unique one.
import string
from django.utils.crypto import get_random_string
def unique_slugify(instance, slug):
model = instance.__class__
unique_slug = slug
while model.objects.filter(slug=unique_slug).exists():
unique_slug = slug + get_random_string(length=4)
return unique_slug
I usually use it by overriding the model save method.
class YourModel(models.Model):
slug = models.SlugField()
title = models.CharField()
def save(self, *args, **kwargs):
if not self.slug:
self.slug = unique_slugify(self, slugify(self.title))
super().save(*args, **kwargs)
This is the simple and small code i am using for generating unique slug,
you only need one field to create your unique slug field
from random import randint
def save(self, *args, **kwargs):
if Post.objects.filter(title=self.title).exists():
extra = str(randint(1, 10000))
self.slug = slugify(self.title) + "-" + extra
else:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
I hope you like this.
This is a simple implementation that generate the slug from the title, it doesn't depend on other snippets:
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()
Django provides a SlugField model field to make this easier for you. Here's an example of it in a "blog" app's
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,)
Note that we've set unique=True for our slug field — in this project we will be looking up posts by their slug, so we need to ensure they are unique. Here's what our application's views.py might look like to do this:
from .models import Post
def post(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post.html', {
'post': post,
})
from django.utils.text import slugify Helps a lot and has quite clear Concepts.
Here one example on How to auto-generate slug by using from django.utils.text import slugify
utils.py
from django.utils.text import slugify
import random
import string
# Random string generator
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
# Unique Slug Generator
def unique_slug_generator(instance, new_slug=None):
"""
It assumes your instance has a model with a slug field and a title character (char) field.
"""
if new_slug is not None:
slug = new_slug
else:
slug = slugify(instance.title)
Klass = instance.__class__
qs_exists = Klass.objects.filter(slug=slug).exists()
if qs_exists:
new_slug = "{slug}-{randstr}".format(slug=slug, randstr=random_string_generator(size=4))
return unique_slug_generator(instance, new_slug=new_slug)
return slug
models.py
from django.db.models.signals import pre_save # Signals
# import the unique_slug_generator from .utils.py
from .utils import unique_slug_generator
class Product(models.Model):
title = models.CharField(max_length=120)
# set blank to True
slug = models.SlugField(blank=True, unique=True)
def product_pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(product_pre_save_receiver, sender=Product)
Django documentation explains Django.utils.text import slugify to generate slug automatically. You can read more detail here
After implementing the code, while creating product, you may leave the slug field blank, which will be further aquired with auto generated slug for the product which will be unique in this case.
Hi can you tried this function
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 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.
def save(self, *args, **kwargs):
self.slug =self.get_unique_slug(self.id,self.title,Training.objects)
return super(Training, self).save(*args, **kwargs)
def get_slug(self):
slug = slugify(self.title.replace("ı", "i"))
unique = slug
number = 2
while Model.objects.filter(slug=unique).exists():
unique = "{}-{}".format(slug, number)
number += 1
return unique
Best solution for me:
def get_slug(self):
slug = slugify(self.title)
unique_slug = slug
number = 1
while Recipe.objects.filter(slug=unique_slug).exists():
unique_slug = f'{slug}-{number}'
number += 1
return unique_slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.get_slug()
return super().save(*args, **kwargs)
This code can generate slug like this:
string-slug
string-slug-1 (if previous alredy exists)
string-slug-2 (if previous alredy exists)
and so on...
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()
Try this, worked out for me,welcome in advance:
class Parcel(models.Model):
title = models.CharField(max_length-255)
slug = models.SlugField(unique=True, max_length=255)
weight = models.IntegerField()
description = models.CharField(max_length=255)
destination = models.CharField(max_length=255)
origin = models.CharField(max_length=255)
def __str__(self):
return self.description
def save(self, *args, **kwargs):
if not self.slug:
t_slug = slugify(self.title)
startpoint = 1
unique_slug = t_slug
while Parcel.objects.filter(slug=unique_slug).exists():
unique_slug = '{} {}'.format(t_slug, origin)
origin += 1
self.slug = unique_slug
super().save(*args, **kwargs)