Reputation: 7940
I have a view to list a certain model (lets call it class A
), like this:
class BaseListView(ListView, MultipleObjectMixin):
http_method_names = ['get']
order_field = None
def get_paginate_by(self, queryset):
session_manager = SessionManager(self.request.session)
return session_manager.paginate_by.get()
def get_context_data(self, **kwargs):
context = super(BaseListView, self).get_context_data(**kwargs)
session_manager = SessionManager(self.request.session)
session_manager.paginate_by.set_to(context)
return context
This view did just what was needed, till now. Now I have to compare the list of objects it retrieves with another list of objects (class B
).
The objects of class A
and B
both have a primary key with their name.
I want to check if any of the objects from class A
has the same name
(primary key) as any of the objects in class B
. In case there is an instance of A
in B
I would like to add a certain parameter or something like is_in_B=True
.
I need this so that I can represent these instances of A
in a different way in the template.
How could I do this?
This is what I have come up with by myself for the moment:
class AListView(BaseListView):
model = "A"
def get_queryset(self):
queryset = super(AListView, self). get_query_set()
all_objects_A = A.objects.all()
all_objects_B = B.objects.all()
# modify queryset to indicate which instances of A are present in B
# No idea how to do this
return queryset
I'm not really sure this is an appropiate approach.
Also, how am I supposed to modify the queryset
returned by my class so that I can indicate which instances of class A
share the same name
as any of the instances of class B
?
Upvotes: 2
Views: 607
Reputation: 31474
You can annotate your queryset with a conditional expression to achieve this:
from django.db.models import Case, When, Value
def get_queryset(self):
# This gives you the queryset of A objects
queryset = super(AListView, self).get_queryset()
# List of primary keys of B objects
all_objects_B = B.objects.all().values_list('pk',flat=True)
# modify queryset to indicate which instances of A are present in B
return queryset.annotate(
is_in_b=Case(When(pk__in=all_objects_B, then=Value(True)),
default=Value(False))
)
)
Your queryset objects will now have an is_in_b
property.
This will work fine if your list of B objects is small. If it is large then I am not sure it is very efficient, and you may need to develop this further to see whether the check (is A in B) can be done directly in the database (possibly requiring raw SQL).
Upvotes: 1