Using django how can I combine two queries from separate models into one query?
I would suggest that you use Model inheritance.
Create a base model that contains date and title. Subclass Msg1 and Msg2 off it as described. Do all your queries (to fill a page) using the base model and then switch to the derived type at the last moment.
The really great thing about inheritance is that django then allows you to use the base model in foreign keys from other models, so you can make your whole application more flexible. Under the hood it is just a table for the base model with a table per sub-model containing one-to-one keys.
How to merge two different querysets with one common field in to one in django?
You can try this way to capture all the values.
from django.db.models import Subquery, OuterRef, FloatField
from django.db.models.functions import Cast
subquery_qs = proc_order_qs.filter(product_id=OuterRef('product_id')
combined_qs = sales_order_qs.annotate(
proc_qty = Cast(Subquery(subquery_qs.values('proc_qty')[:1]), output_field=FloatField()),
proc_price = Cast(Subquery(subquery_qs.values('proc_price')[:1]), output_field=FloatField()))
And then you can get all the values in combined_qs
combined_qs.values('product_id','sales_qty','sales_price','proc_qty', 'proc_price')
How can I combine two or more querysets in a Django view?
Concatenating the querysets into a list is the simplest approach. If the database will be hit for all querysets anyway (e.g. because the result needs to be sorted), this won't add further cost.
from itertools import chain
result_list = list(chain(page_list, article_list, post_list))
Using itertools.chain
is faster than looping each list and appending elements one by one, since itertools
is implemented in C. It also consumes less memory than converting each queryset into a list before concatenating.
Now it's possible to sort the resulting list e.g. by date (as requested in hasen j's comment to another answer). The sorted()
function conveniently accepts a generator and returns a list:
result_list = sorted(
chain(page_list, article_list, post_list),
key=lambda instance: instance.date_created)
If you're using Python 2.4 or later, you can use attrgetter
instead of a lambda. I remember reading about it being faster, but I didn't see a noticeable speed difference for a million item list.
from operator import attrgetter
result_list = sorted(
chain(page_list, article_list, post_list),
key=attrgetter('date_created'))
How to combine two Querysets into one from different models?
You can't do it at the database or queryset level unfortunately because those two things don't exist in the same database table. You can do it on the python side (though it's slower and more computationally intensive).
Assuming that both Cars and Horses have a "date" attribute, you can do this:
cars = Cars.objects.all().filter(color='red')
horses = Horses.objects.all()
all_things = list(cars) + list(horses)
sorted_things = sorted(all_things, key=lambda x: x.date)
Another option (which is inefficient on the database level) would be to make them all inherit from the same non-abstract model.
class Item(models.Model):
date = models.DateTimeFiedl()
item_type = models.CharField(max_length=255)
def get_instance(self):
if self.item_type = 'car':
return Car.objects.get(id=self.id)
elif self.item_type == 'horse':
return Horse.objects.get(id=self.id)
class Car(Item):
color = models.CharField(max_length=12)
def save(self, *args, **kwargs):
self.item_type = 'car'
super(Car, self).save(*args, **kwargs)
class Horse(Item):
breed = models.CharField(max_length=25)
def save(self, *args, **kwargs):
self.item_type = 'horse'
super(Horse, self).save(*args, **kwargs)
With that, you can do
items = Item.objects.all().order_by('date')
for item in items:
print(type(item)) # Always "Item"
actual_item = item.get_instance()
if type(actual_item) == Car:
print("I am a car")
else:
print("I am a horse")
While iterating through them grab each specific item as needed (similar to how Wagtail handles pages, you make a convenience method for grabbing an object based on its parent class)
Merge two queries in one single query in django
I think you're making this a bit more complicated than necessary -- the Django ORM handles much of this for you, thanks to that foreign-key relationship. Given an ID for ModelB, the ID for the other ModelB with the same ModelA but where base=True is just:
ModelB.objects.get(id=modelb_pk).modela.modelb_set.get(base=True).id
Why does this work?
- Because ModelB has a many-to-one relationship with ModelA, we can call
.modela
on an instance of ModelB to get the corresponding ModelA. - Conversely, given an instance of ModelA, calling
.modelb_set
returns all ModelB records associated with ModelA. - We can then call
.get
/.filter
onmodelb_set
just like we would withModelB.objects
.
How can i combine these two Django annotated queries into one?
You can pass a filter to Sum to restrict which values are used, you can then have two filtered annotations in the same query
from django.db.models import Sum, Q
Users.objects.annotate(
likes=Sum('comments__likedislike', filter=Q(comments__likedislike__gt=0)),
dislikes=Sum('comments__likedislike', filter=Q(comments__likedislike__lt=0))
)
Related Topics
Sqlite Inner Join - Update Using Values from Another Table
Rails/Postgres: "Must Appear in the Group by Clause or Be Used in an Aggregate Function"
How to Create Daylight Savings Time Start and End Function in SQL Server
How to Concatenate All Columns in a Select with SQL Server
Postgres Interval Using Value from Table
How to Get Value Using Join Table with Different Values
How to Copy a Row from One SQL Server Table to Another
Ms SQL Server - When Is a Cursor Good
Sorting on the Server or on the Client
Oracle Convert Timestamp with Timezone to Date
Rails .Where() Query Not Working
How to Perform Update Query with Subquery in Access
Update Multiple Columns in a Trigger Function in Plpgsql
Select Distinct Is Slower Than Expected on My Table in Postgresql
Oracle Get Checksum Value for a Data Chunk Defined by a Select Clause