283π
Try:
from django.db.models import Count
Literal.objects.values('name')
.annotate(Count('id'))
.order_by()
.filter(id__count__gt=1)
This is as close as you can get with Django. The problem is that this will return a ValuesQuerySet
with only name
and count
. However, you can then use this to construct a regular QuerySet
by feeding it back into another query:
dupes = Literal.objects.values('name')
.annotate(Count('id'))
.order_by()
.filter(id__count__gt=1)
Literal.objects.filter(name__in=[item['name'] for item in dupes])
64π
This was rejected as an edit. So here it is as a better answer
dups = (
Literal.objects.values('name')
.annotate(count=Count('id'))
.values('name')
.order_by()
.filter(count__gt=1)
)
This will return a ValuesQuerySet
with all of the duplicate names. However, you can then use this to construct a regular QuerySet
by feeding it back into another query. The django ORM is smart enough to combine these into a single query:
Literal.objects.filter(name__in=dups)
The extra call to .values('name')
after the annotate call looks a little strange. Without this, the subquery fails. The extra values tricks the ORM into only selecting the name column for the subquery.
- [Django]-Django proxy model and ForeignKey
- [Django]-How to rename items in values() in Django?
- [Django]-Django Rest Framework β Authentication credentials were not provided
12π
try using aggregation
Literal.objects.values('name').annotate(name_count=Count('name')).exclude(name_count=1)
- [Django]-Django celery task: Newly created model DoesNotExist
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
- [Django]-Django form: what is the best way to modify posted data before validating?
7π
In case you use PostgreSQL, you can do something like this:
from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import Func, Value
duplicate_ids = (Literal.objects.values('name')
.annotate(ids=ArrayAgg('id'))
.annotate(c=Func('ids', Value(1), function='array_length'))
.filter(c__gt=1)
.annotate(ids=Func('ids', function='unnest'))
.values_list('ids', flat=True))
It results in this rather simple SQL query:
SELECT unnest(ARRAY_AGG("app_literal"."id")) AS "ids"
FROM "app_literal"
GROUP BY "app_literal"."name"
HAVING array_length(ARRAY_AGG("app_literal"."id"), 1) > 1
- [Django]-Determine variable type within django template
- [Django]-How do you change the collation type for a MySQL column?
- [Django]-Django REST Framework : "This field is required." with required=False and unique_together
2π
Ok, so for some reason none of the above worked for, it always returned <MultilingualQuerySet []>
. I use the following, much easier to understand but not so elegant solution:
dupes = []
uniques = []
dupes_query = MyModel.objects.values_list('field', flat=True)
for dupe in set(dupes_query):
if not dupe in uniques:
uniques.append(dupe)
else:
dupes.append(dupe)
print(set(dupes))
- [Django]-How to use permission_required decorators on django class-based views
- [Django]-Django: How to format a DateField's date representation?
- [Django]-Separation of business logic and data access in django
0π
If you want to result only names list but not objects, you can use the following query
repeated_names = Literal.objects.values('name').annotate(Count('id')).order_by().filter(id__count__gt=1).values_list('name', flat='true')
- [Django]-How to access a dictionary element in a Django template?
- [Django]-How to convert a Django QuerySet to a list?
- [Django]-Embed YouTube video β Refused to display in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'