简体   繁体   中英

Django - Slugs - Key (slug)=() is duplicated

just started fooling around with Django and came across a link here on how to create slugs. I was told to perform the following changes to an existing model:

from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    views = models.IntegerField(default=0)
    likes = models.IntegerField(default=0)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name

This worked out pretty well until I tried to migrate the database using:

python manage.py makemigrations

The above asked for a default value so following the guide, I gave it ''. Then:

python manage.py migrate

The above returned "DETAIL: Key (slug)=() is duplicated."

I'm not entirely sure why this happened. Perhaps it's because I'm adding a new field that is unique and I can't populate it with ''? If so, what do I have to do in order to populate the database?

The documentation explains how to migrate in these circumstances . A quick summary:

  • create the field without unique=True
  • create a migration with a RunPython function that iterates through all Categories and calls save on them, which will populate the slug
  • create a final migration which sets unique=True.

Actually i found an easier way to override the admin filter lists, that fixed my error of duplicated fields, So you can filter the fields in the admin panel to get all the duplicated fields and rename them ... and then migrate .. and it will work after removing all the duplication..

first create custom_filter.py file and include this code in it(assuming that you have a field with name slug)

from django.contrib.admin import SimpleListFilter


class DuplicatSlugFilter(SimpleListFilter):
    """
    This filter is being used in django admin panel.
    """

    title = "Duplicates"
    parameter_name = "slug"

    def lookups(self, request, model_admin):
        return (("duplicates", "Duplicates"),)

    def queryset(self, request, queryset):
        if not self.value():
            return queryset
        if self.value().lower() == "duplicates":
            return queryset.filter().exclude(
                id__in=[slug.id for slug in queryset.distinct("slug").order_by("slug")]
            )

Then add those lines to the admin.py file:

from .custom_filter import DuplicatSlugFilter


class CategoryAdmin(admin.ModelAdmin):
    list_filter = (DuplicatSlugFilter,)

admin.site.register(Category, CategoryAdmin)

Good Luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM