1👍
You cannot exclude slug from admin fields since you are including it in prepopulated_fields. However, you can override your model’s save method like below to generate a unique slug. You can make general BaseModel with this save method and extend your models with slug fields everytime:
from django.utils.text import slugify
def generate_unique_slug(klass, field):
"""
return unique slug if origin slug is exist.
eg: `foo-bar` => `foo-bar-1`
:param `klass` is Class model.
:param `field` is specific field for title.
"""
origin_slug = slugify(field)
unique_slug = origin_slug
numb = 1
while klass.objects.filter(slug=unique_slug).exists():
unique_slug = "%s-%d" % (origin_slug, numb)
numb += 1
return unique_slug
class BaseModel(models.Model):
class Meta:
abstact = True
def save(self, *args, **kwargs):
if hasattr(self, "slug") and hasattr(self, "title"):
if self.slug:
if slugify(self.title) != self.slug:
self.slug = generate_unique_slug(self.__class__, self.title)
else: # create
self.slug = generate_unique_slug(self.__class__, self.title)
super().save(*args, **kwargs)
class Foo(BaseModel):
title = models.CharField()
slug = models.SlugField()
# remaining fields listed below
class AnotherModelWithSlug(BaseModel):
title = models.CharField()
slug = models.SlugField()
0👍
You can override the form of the admin:
from django.utils.text import slugify
class FooAdmin(admin.ModelAdmin):
fieldsets = [
('General', {
'fields': [
'title',
'description',
'information',
'cover_photo',
'gallery',
]
}),
('Details', {
'fields' : [
'is_cancelled',
'start',
'finish',
'video_url',
]
}),
]
def get_form(self, request, obj=None, change=False, **kwargs):
OriginalForm = super().get_form(request, obj, change, **kwargs)
class Form(OriginalForm):
def save(self, commit=True):
instance = super().save(commit=False)
instance.slug = slugify(instance.title) # Here
if commit:
instance.save()
return instance
return Form
As you said the best (and simplest) solution would be to override the save
method of the model.
Source:stackexchange.com