Skip to content

Instantly share code, notes, and snippets.

@jourdanrodrigues
Created May 7, 2020 17:38
Show Gist options
  • Save jourdanrodrigues/c28ca7ebc79ef081a7c742a47353aa33 to your computer and use it in GitHub Desktop.
Save jourdanrodrigues/c28ca7ebc79ef081a7c742a47353aa33 to your computer and use it in GitHub Desktop.
from django.db.models import QuerySet as DjangoQuerySet
class QuerySet(DjangoQuerySet):
def filter_or_create(self, filters: List[dict], defaults=None, lookup='pk'):
"""
Fetch existing records and create missing ones in 2 queries
@param filters: List of queryset filters as dictionaries
@param defaults: Same as QuerySet.get_or_create's "defaults"
@param lookup: Field that must be used to check whether the record exists or not (filters must have it)
"""
to_create = []
filter_ = Q()
for item in filters:
filter_ |= Q(**item)
instances = list(self.filter(filter_)) # 1st query
existing_lookups = {getattr(instance, lookup) for instance in instances}
for item in filters:
if item[lookup] not in existing_lookups:
instance = self.model(**item, **defaults)
instances += [instance]
to_create += [instance]
self.bulk_create(to_create) # 2nd query
return instances
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment