JOIN Two table in DJANGO with aggregate - django

I've been playing around with django for a month now and i'm stuck with JOINING Two tables with Aggregate with it. Here's my models.py
class Student(models.Model):
student_number_format = RegexValidator(regex=r"^20{1,2}[1-2][0-9]-[0-9]{6}", message="Please enter a valid student number (example:2019-123456)")
student_number = models.CharField(validators=[student_number_format], max_length=11, blank=True, unique=True, help_text="Student number must be this format 20YY-99999")
student_course = models.ForeignKey(Course, on_delete=models.CASCADE)
first_name = models.CharField(max_length=255)
middle_initial = models.CharField(max_length=2)
last_name = models.CharField(max_length=255)
profile_picture = models.ImageField(upload_to=user_directory_path)
date_registered = models.DateTimeField(default=timezone.now)
class DataSets(models.Model):
student_info = models.ForeignKey(Student, on_delete=models.CASCADE)
dataset_image = models.ImageField(upload_to=dataset_directory_path)
date_upload = models.DateTimeField(default=timezone.now)
In here i have two models the DataSets class have a Foreign Key to Student. And i want to show only is Students that have 5 or more data inside DataSets. Here's the SQL representation:
SELECT Count(student_info) as Count, A.first_name as Name
FROM Student A
JOIN DataSets B ON A.id = B.student_info_id
WHERE Count >= 5

You can do this with select_relatedlink . I hope following query will work.
DataSets.objects.select_related('student_info').annotate(
entries=models.count()).filter(entries__gte=5)

Related

Group By Django queryset by a foreignkey related field

I have a model Allotment
class Kit(models.Model):
kit_types = (('FLC', 'FLC'), ('FSC', 'FSC'), ('Crate', 'Crate'), ('PP Box', 'PP Box'))
kit_name = models.CharField(max_length=500, default=0)
kit_type = models.CharField(max_length=50, default=0, choices=kit_types, blank=True, null=True)
class AllotmentFlow(models.Model):
flow = models.ForeignKey(Flow, on_delete=models.CASCADE)
kit = models.ForeignKey(Kit, on_delete=models.CASCADE)
asked_quantity = models.IntegerField(default=0)
alloted_quantity = models.IntegerField(default=0)
class Allotment(models.Model):
transaction_no = models.IntegerField(default=0)
dispatch_date = models.DateTimeField(default=datetime.now)
send_from_warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
flows = models.ManyToManyField(AllotmentFlow)
For a stacked graph I am trying to get the data of different kit_type alloted in different months.
For that I have tried annotate but it isn't getting the desired results
dataset = Allotment.objects.all().annotate(
month=TruncMonth('dispatch_date')).values(
'month').annotate(dcount=Count('flows__kit__kit_type')).values('month', 'dcount')
Expected Output:
[{'month':xyz, 'kit_type':foo, count:123},...]
I am getting the month and count of kit type from above but how do I segregate it by kit_type?
having a field that represents your choice field names in this query is difficult
instead how about use the Count filter argument and annotate to get what you want
dataset = Allotment.objects.all().annotate(month=TruncMonth('dispatch_date')).values('month').annotate(
FLC_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="FLC")),
FSC_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="FSC")),
Crate_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="Crate")),
PP_Box_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="PP_Box")),
).values('month', 'FLC_count', 'FSC_count', 'Crate_count', 'PP_Box_count')

django models related manager

I want to develop DJANGO Application for rooms booking.
I want to use following TWO models.
class Room(models.Model):
room_no = models.IntegerField()
remarks = models.CharField(max_length=100)
def __str__(self):
return self.remarks
class Roombooking(models.Model):
room = models.ForeignKey(Room, related_name= 'roombookingforroom', on_delete=models.CASCADE)
booked_for_date = models.DateField(blank=True, null=True)
booked_by = models.TextField(max_length=1000, default='')
remarks = models.CharField(max_length=100,)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["suit", "booked_for_date"],
name="unique_room_date",
),
]
def __str__(self):
return self.room.remarks
To avoid assigning one room to 2 different persons on any day, “ UniqueConstraint” is used.
Now, how to query the list of rooms which are vacant from DATE1 to DATE2
You can just filter the room booking by date
gte = greater than or equal to
lte = lower than or equal to
query = Roombooking.objects.filter(booked_for_date__gte=DATE1, booked_for_date__lte=DATE2)
*Note that DATE1 and DATE2 should be datetime type
You can have a look on official documentation

Is there a way i can join two tables and get the sum of duplicated field in Django

I have a model WarehouseTrade Account and WarehouseStorage Account
it look like this:-------
class WarehouseStorageAccount(models.Model):
warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE, null=True)
item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True)
grade = models.CharField(max_length=5, choices=ITEM_GRADE_CHOICES)
bags = models.IntegerField(default=0)
gross_weight = models.DecimalField(max_digits=20, decimal_places=3, default=0)
net_weight = models.DecimalField(max_digits=20, decimal_places=3, default=0)
updated = models.DateTimeField(auto_now=True)
class WarehouseTradeAccount(models.Model):
warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE, null=True)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
grade = models.CharField(max_length=5, choices=ITEM_GRADE_CHOICES)
bags = models.IntegerField(default=0)
gross_weight = models.DecimalField(max_digits=20, decimal_places=3, default=0)
net_weight = models.DecimalField(max_digits=20, decimal_places=3, default=0)
updated = models.DateTimeField(auto_now=True)
I am trying to get All the data in both accounts, but it should sum it up if there is a duplicate between the two.
I have been able to achieve this with SQL using below code:
SELECT
data.warehouse_id AS Warehouse,
data.item_id AS Item,
data.grade AS Grade,
SUM((data.net_weight)) AS Net_WEIGHT,
SUM((data.gross_weight)) AS Gross_WEIGHT,
SUM((data.bags)) AS Bags
FROM
(SELECT warehouse_id, item_id, net_weight, grade, gross_weight, bags FROM public.inventory_warehousestorageaccount
UNION ALL
SELECT warehouse_id, item_id, net_weight, grade, gross_weight, bags
FROM public.inventory_warehousetradeaccount
) data
GROUP BY data.warehouse_id, data.item_id, data.grade
I tried using union to join the two tables, then get the aggregate the result, but I keep getting an error
wt = WarehouseTradeAccount.objects.all()
ws = WarehouseStorageAccount.objects.all()
w=wt.union(ws)
w.aggreate(new_net_weight=Sum('net_weight')
How do I replicate this in Django?
I actually didn't understand what do you mean by
it should sum it up if there is a duplicate between the two
Do you want to remove the duplicates?
attributes = ('warehouse','item','grade'....)
result = []
wt = WarehouseTradeAccount.objects.all()
ws = WarehouseStorageAccount.objects.all()
for wtobj, wsobj in zip(wt,ws):
for attribute in attributes:
if getattr(wtobj, attribute) != getattr(wsobj, attribute):
result.append(wtobj, wsobj)
break
else:
result.append(wtobj)

how can i get data manytomay relation from 3 tables django

class Product(models.Model):
name = models.CharField(max_length=30)
class Order(models.Model):
order_number = models.CharField(max_length=30)
products = models.ManyToManyField(
Product,
through='OrderProduct',
related_name='orders'
)
class OrderProduct(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
price = models.CharField(max_length=30)
quantity = models.IntegerField(null = True)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
my data is already save in these Models now when i fetch order then i want to see Order product data also how can i see these data ?
again 1 order has multi order products
i try this
abc = Order.object.get(id = 1)
now how can i see the related products and its quantity and price?
Please try this.
abc = Order.object.get(id = 1)
OrdProducts = abc.product.all()
OrdProducts = abc.product.all()
for ord in OrdProducts:
print(ord.product)
print(ord.price)
print(ord.quantity)

Table as field in model

I have such models:
class Department(models.Model):
name = models.CharField(max_length=30)
schedule = models.ForeignKey('Schedule', on_delete=models.CASCADE)
class Schedule(models.Model):
post_name = models.CharField(max_length=30)
shift_start = models.TimeField(auto_now=False, auto_now_add=False)
shift_end = models.TimeField(auto_now=False, auto_now_add=False)
Each department have a schedule - some [post_name, shift_start, shift_end] lines for each post. If use ForeignKey there will be only one line instead of a list. Is it possible to create some Schedule tables and link each with certain Department?
Foreign key defines a 1 to N relationship between your models. If I understood right you would like 1 department to have N schedules. To achieve this each schedule should have a foreign key defining which department it belongs to.
So you should use ForeignKey for that, but put it in your Schedule model.
Here is how it should look:
class Department(models.Model):
name = models.CharField(max_length=30)
class Schedule(models.Model):
post_name = models.CharField(max_length=30)
shift_start = models.TimeField(auto_now=False, auto_now_add=False)
shift_end = models.TimeField(auto_now=False, auto_now_add=False)
department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name='schedules')
Then after you've created a department and a couple of schedules for that department you can access them like so:
(lets assume the created department primary key is 1)
Department.objects.get(pk=1).schedules.all()