Max column value of related django model where condition is true - django

TAssignment model has many entries related to TSlot model like for 1 pk of TSlot model there are many entries in TAssignment model.Now this queries outputs values from Tslot table and also latest related created on and updated on from Tassignment table.But what i want is latest value of
'assignment_Slot__created_on' and 'assignment_Slot__updated_on' when assignment_Slot__is_deleted=False.
QUESTION: How to add "assignment_Slot__is_deleted=False" condition along with 'assignment_Slot__created_on' and 'assignment_Slot__updated_on' inside annotate without duplicating results.
** assignment_Slot here is related name
TSlot.objects.filter(request__id=request_id, is_deleted=False
).values("slot_date", "type_of_work", "reason_for_less_assign", "request_id","slot", "remarks",
slot_id=F("id"), request_status=F('request__request_status')).annotate(
assigned_on=Max('assignment_Slot__created_on'), modified_on =Max('assignment_Slot__modified_on'))

Add a filter to your annotations, see filtering on annotations
from django.db.models import Max, Q, DateField
TSlot.objects.filter(...).annotate(
assigned_on=Max('assignment_Slot__created_on', filter=Q(assignment_Slot__is_deleted=False), output_field=DateField()),
modified_on=Max('assignment_Slot__modified_on', filter=Q(assignment_Slot__is_deleted=False), output_field=DateField())
)

Related

summing up the values of a column in django framework

I have a model in my django web app and I have been trying to query the model in such a way that I can sum up values in the quantity column. I already have data in this model so I just need to add up all the values in the quantity column.
class ProductInstance(models.Model):
product=models.ForeignKey(Product,on_delete=models.RESTRICT,related_name='product')
quantity=models.IntegerField()
warehouse=models.ForeignKey(Warehouse,on_delete=models.RESTRICT,related_name='warehouse')
I tried "ProductInstance.objects.sum(quantity)". It didnt work
You can use aggregate functions for this kind of cases.
from django.models import Sum
ProductInstance.objects.all().aggregate(sum=Sum('quantity'))

How to populate table based on the condition of another table's column value in Django

I am kinda new in django and I am stuck.
I am building and app to store equipment registry. I have done a model for equipment list and i have a status values as "available", "booked", "maintenance"
I also have a model for all equipment that are not available. not in my html in the "not available registry" i want to show only details of equipment in the list that are marked as "booked" and "maintenance"
There are three ways of doing this.
To filter out objects of the model that are marked as "booked" or "maintenance" you can use complex lookups with Q objects. It allows you to filter objects with OR statement. Here you need to find objects that have status set to "booked" OR to "maintenance". The query should look like this:
from django.db.models import Q
Equipment.objects.filter(Q(status='booked') | Q(status='maintetnance'))
Second way of doing this is by using __in statement to filter objects that you need:
not_available_status = ['booked', 'maintenance']
Equipment.objects.filter(status__in=not_available_status)
And final way is to exclude objects that you don't need:
Equipment.objects.exclude(status='available')

How to limit prefetch_related data in django

I've two tables brand and a product. each brand has multiple products.
So. I used prefetch_related to get related products for a particular brand with only a minimum product price. but the problem is when I have 2 products with the same price it selects both records so how to limit this?
alternatives_data = Brand.objects.filter(category__category_slug = category_slug).prefetch_related(
Prefetch('products', queryset=Product.objects.annotate(
min_brand_price=Min('brand__products__product_price')
).filter(
product_price=F('min_brand_price')
).order_by('product_id')))
i tried everything but nothing work!
To prevent a query to return multiple records with duplicata in specific columns, use the distinct method.
In your case, add .distinct('price') to the Product queryset inside the prefetch.
There is however one caveat : It is supported on PostgreSQL only.
Documentation

Is is possible to decrease connection that made to db?

Currently, my Django application has millions of records and I want to update based on it's ManyToMany related fields value.
Consequently what I did works, but it took so many times. In order to update only three records, it uses 13 queries.
Record model has genres field which is ManyToMany field. Also, has authors field which is also ManyToMany field.
And lastly, Author model has ManyToMany field that implies genres.
for i in Record.objects.filter(authors__popular=True).only("authors", "genres"):
for a in i.authors.all():
print(a.name) # test purpose
for genre in i.genres.all():
if a.genres.exists():
a.genres.add(genre)
When i run len(connection.queries) it shows query numbers that ran, i want it to be lesser than 13.
So far i just decreased query number to 1 for 1 record. This is how i achieved
for i in Author.objects.annotate(record_count=Count('record'), record_genres=ArrayAgg('record__genres', distinct=True):
if i.record_count > 0 and i.record_genres:
i.genres.set(i.record_genres)
i.save()

Django - joining multiple tables (models) and filtering out based on their attribute

I'm new to django and ORM in general, and so have trouble coming up with query which would join multiple tables.
I have 4 Models that need joining - Category, SubCategory, Product and Packaging, example values would be:
Category: 'male'
SubCategory: 'shoes'
Product: 'nikeXYZ'
Packaging: 'size_36: 1'
Each of the Model have FK to the model above (ie. SubCategory has field category etc).
My question is - how can I filter Product given a Category (e.g. male) and only show products which have Packaging attribute available set to True? Obviously I want to minimise the hits on my database (ideally do it with 1 SQL query).
I could do something along these lines:
available = Product.objects.filter(packaging__available=True)
subcategories = SubCategory.objects.filter(category_id=<id_of_male>)
products = available.filter(subcategory_id__in=subcategories)
but then that requires 2 hits on database at least (available, subcategories) I think. Is there a way to do it in one go?
try this:
lookup = {'packaging_available': True, 'subcategory__category_id__in': ['ids of males']}
product_objs = Product.objects.filter(**lookup)
Try to read:
this
You can query with _set, multi __ (to link models by FK) or create list ids
I think this should work but it's not tested:
Product.objects.filter(packaging__available=True,subcategori‌​es__category_id__in=‌​[id_of_male])
it isn't tested but I think that subcategories should be plural (related_name), if you didn't set related_name, then subcategory__set instead od subcategories should work.
Probably subcategori‌​es__category_id__in=‌​[id_of_male] can be switched to .._id=id_of_male.