Django: Annotate to find duplicates and delete

The django-taggit library allows you to add a Tag for any resource in your Django site. The 1.X release of django-taggit includes a breaking change to add a unique constraint.

1.0.0 (2019-03-17)
Backwards incompatible: Remove support for Python 2.
Added has_changed() method to taggit.forms.TagField.
Added multi-column unique constraint to model TaggedItem on fields content_type, object_id, and tag. Databases that contain duplicates will need to add a data migration to resolve these duplicates.
Fixed TaggableManager.most_common() to always evaluate lazily. Allows placing a .most_common() query at the top level of a module.
Fixed setting the related_name on a tags manager that exists on a model named Name.

This means that any Custom Tag that was built under the 0.X version of django-taggit will need to have the duplicates removed from custom TaggedItem model class before the unique constraint can be applied. Here’s an example of how to use annotate to identify duplicate entries and save and exclude the initial row from the delete.

duplicate_tags = MYMODEL.objects.filter(content_type_id=FILTERED_CONTENT_ID)
    .values("object_id", "content_type_id", "tag_id")
    .annotate(count=Count("object_id"))
    .annotate(save_id=Min("id"))
    .filter(count__gt=1)
    .values_list("save_id", "object_id", "content_type_id", "tag_id")
for save_id, object_id, content_type_id, tag_id in duplicate_tags:
        MYMODEL.objects.filter(
            object_id=object_id, 
            content_type_id=content_type_id, 
            tag_id=tag_id
        ).exclude(id=save_id).delete()

Django: Request object has no attribute “accepted_renderer”

If you get the error Request object has no attribute “accepted_renderer” or WSGIRequest object has no attribute “accepted_renderer” when using Django Rest Framework and attempting to add a custom BaseRenderer, then there are a few issues that may be causing this. Two of the most prevalent are:

  1. Missing pyyaml dependency

    https://github.com/encode/django-rest-framework/issues/6300

    When attempting to use the rest_framework.schemas get_schema_view, Django Rest Framework requires pyyaml


    Solution #1:

    Install pyyaml

    pip install pyyaml

    Solution #2:

    Use a version of Django Rest Framework that doesn’t require pyyaml for schema

    pip install djangorestframework==3.8.0

  2. Invalid renderers settings

When setting renderer_classes it’s important to use the api_settings from rest_framework instead of the DEFAULT_RENDERER_CLASSES from your REST_FRAMEWORK Django settings.

from rest_framework.settings import api_settings

renderer_classes = tuple(api_settings.DEFAULT_RENDERER_CLASSES) + (CSVRenderer,)

https://www.django-rest-framework.org/api-guide/settings/