Created
May 7, 2020 17:38
-
-
Save jourdanrodrigues/c28ca7ebc79ef081a7c742a47353aa33 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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