django - Using Q object in list comprehension -
i have following code:
def get_elements(self, obj): book_elements = element.objects.filter(book__pk=obj.id) elements = element.objects.filter( (q(book__pk=obj.id) | q(theme__pk=obj.theme_id)), ~q(pk__in = [o.element_id o in book_elements if o.element_id])) serializer = getelementserializer(elements, context=self.context, many=true) the elements variable query using q object implementation. however, q(book__pk=obj.id) , book_elements reference exact same set of values. how can reference q(book__pk=obj.id) inside of list comprehension avoid having run 2 queries. following:
def get_elements(self, obj): elements = element.objects.filter( (q(book__pk=obj.id) | q(theme__pk=obj.theme_id)), ~q(pk__in = [o.element_id o in q(book__pk=obj.id) if o.element_id])) serializer = getelementserializer(elements, context=self.context, many=true) my element model requested:
class element(models.model): name = models.charfield(max_length=100) pub_date = models.datetimefield('date published', auto_now_add=true) mod_date = models.datetimefield('modified date', auto_now=true) book = models.foreignkey(book, blank=true, null=true, related_name='elements') book_part = models.foreignkey(bookpart) theme = models.foreignkey(theme, blank=true, null=true, related_name='elements') element = models.foreignkey('self', blank=true, null=true, related_name='parent') def __str__(self): return self.name any appreciated!
here 1 query sub-query solution:
elements = element.objects.filter( (q(book__pk=obj.id) | q(theme__pk=obj.theme_id)), ~q(pk__in = element.objects.filter( book__pk=obj.id, element__isnull=false ).values_list('element', flat=true) ) ) this hit database once.
btw, after reading trying achieve:
get me elements, book_id or theme_id, equals book id & theme id book, excluding elements have fk relationship element in book
in orm fashion think can achieved this:
elements = element.objects \ .filter(q(book_id=book.id)|q(theme_id=book.theme_id)) \ .exclude(element__in=book.elements.all()) #not tested, if throws error transform into: book.elements.values_list('id', flat=true) again hit database once, because querysets lazy , django smart enough transform them sub-query when take apart queryset.
Comments
Post a Comment