How can i make a Query through Many-To-Many-Relationship - django

I want to display the trainer for a course date. A course can have several dates and a different trainer can be used on each date. A trainer can have a different role on each course date. (Instructor, helper...)
How do I make the correct query? Are the models correct for this?
Models:
class Course_dates(models.Model):
date = models.DateField()
start = models.TimeField()
end = models.TimeField()
def __str__(self):
return str(self.id)
"""return self.date.strftime("%d.%m.%Y")"""
class Course(models.Model):
course_number = models.CharField(max_length=24, blank=True)
course_location = models.ForeignKey(Course_location, on_delete=models.CASCADE)
course_dates = models.ManyToManyField('Course_dates', through="Course_Course_dates")
def __str__(self):
return self.course_number
class Trainer_Course_Course_date_role(models.Model):
trainer = models.ForeignKey(Trainer, on_delete=models.CASCADE)
role = models.CharField(max_length=24, blank=True)
def __str__(self):
return str(self.id)
class Course_Course_dates(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
course_dates = models.ForeignKey(Course_dates, on_delete=models.CASCADE)
trainer = models.ForeignKey(Trainer_Course_Course_date_role, on_delete=models.CASCADE, null=True)
def __str__(self):
return str(self.id)
class Trainer(models.Model):
salutation = models.CharField(max_length=8,choices=GENDER_CHOICES)
last_names = models.CharField(max_length=56)
first_names = models.CharField(max_length=56)
date_of_birth = models.DateField()
address = models.ForeignKey(Address, on_delete=models.CASCADE)
email = models.EmailField()
phone = models.CharField(max_length=56, blank=True)
mobile = models.CharField(max_length=56, blank=True)
def __str__(self):
return self.last_names
View:
def course(request):
courses = Course.objects.all()
course_list = []
for course in courses:
sorted_date_list = course.course_dates.all().order_by('date')
course_list.append({'course': course, 'sorted_date_list': sorted_date_list })
context = { 'course_list': course_list, }
return render(request, 'kursverwaltung_tenant/course.html', context)

Related

Summing up total amount from multiple models in Django

The title of my question has said it all. I have multiple models, and I want to add up the amount to derive the total amount, here's my code
class FurnitureItem(models.Model):
fur_title = models.CharField(max_length=200)
fur_price = models.FloatField()
fur_discount_price = models.FloatField(blank=True, null=True)
fur_pictures = models.ImageField(upload_to='Pictures/', blank=True)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
category = models.CharField(choices=CATEGORIES_CHOICES, max_length=24)
fur_descriptions = models.TextField()
slug = models.SlugField()
date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.fur_title
class FurnitureOrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
fur_ordered = models.BooleanField(default=False)
item = models.ForeignKey(FurnitureItem, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f"{self.quantity} of {self.item.fur_title}"
....
def get_final_fur_price(self):
if self.item.fur_discount_price:
return self.get_total_discount_fur_price()
return self.get_total_item_fur_price()
class FurnitureOrder(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
fur_items = models.ManyToManyField(FurnitureOrderItem)
date_created = models.DateTimeField(auto_now_add=True)
ordered_created = models.DateTimeField()
fur_ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
def get_total_fur_everything(self):
total = 0
for fur_order_item in self.fur_items.all():
total += fur_order_item.get_final_fur_price()
return total
class GraphicItem(models.Model):
graphic_title = models.CharField(max_length=200)
graphic_price = models.FloatField()
graphic_discount_price = models.FloatField(blank=True, null=True)
graphic_pictures = models.ImageField(upload_to='Pictures/', blank=True)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
category = models.CharField(choices=CATEGORIES_CHOICES, max_length=24)
graphic_descriptions = models.TextField()
slug = models.SlugField()
date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.graphic_title
class GraphicOrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
graphic_ordered = models.BooleanField(default=False)
item = models.ForeignKey(GraphicItem, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f"{self.quantity} of {self.item.graphic_title}"
....
def get_final_graphic_price(self):
if self.item.graphic_discount_price:
return self.get_total_discount_graphic_price()
return self.get_total_item_graphic_price()
class GraphicOrder(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
graphic_items = models.ManyToManyField(GraphicOrderItem)
date_created = models.DateTimeField(auto_now_add=True)
ordered_created = models.DateTimeField()
graphic_ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
def get_total_graphic_everything(self):
total = 0
for graphic_order_item in self.graphic_items.all():
total += graphic_order_item.get_final_graphic_price()
return total
what i've tried as regards summing up the amount for furniture and graphics
class TotalAmount(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
graphic_items = models.ManyToManyField(GraphicOrderItem)
fur_items = models.ManyToManyField(FurnitureOrderItem)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
def amount(self):
return self.graphic_items.get_total_graphic_everything() + self.fur_items.get_total_fur_everything()
Then my views goes this way:
class Summary(LoginRequiredMixin, View):
def get(self, *args, **kwargs):
try:
fur_order = FurnitureOrder.objects.get(user=self.request.user, fur_ordered=False)
graphic_order = GraphicOrder.objects.get(user=self.request.user, graphic_ordered=False)
amount = TotalAmount.objects.get(user=self.request.user)
context = {
'fur_order':fur_order,'graphic_order':graphic_order,'amount':amount}
return render(self.request, 'business/home-order-summary.html', context)
Thanks for your time, I no the code is lengthy, but I wanted to expanciate better.

Django: method of model from querying a different one

I have a model CartItem that has a ForeignKey to a Product model.
Because from Product model I get the description, image, etc.
However, I want to have a method called sub_total that returns and integer. I use this to calculate total to be paid for this CartItem.
This sub_total method query a different model costo_de_los_productos using some of the properties of CartItem. like: self.product.category.name, self.product.name, self.size, self.quantity.
I need to return an Integer from sub_total method.
However, something is not right with me query, if I comment it and return 0 it works, but total is 0.
def sub_total(self):
product_price = costo_de_los_productos.objects.filter(category=self.product.category.name,
product = self.product.name,
size=self.size,
quantity=self.quantity).values_list("price", flat=True)
What could be wrong?
class CartItem(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
size = models.CharField(max_length=20, choices=TAMANIOS)
quantity = models.CharField(max_length=20, choices=CANTIDADES)
file = models.FileField(upload_to='files', blank=True, null=True)
comment = models.CharField(max_length=100, blank=True, null=True, default='')
uploaded_at = models.DateTimeField(auto_now_add=True)
step_two_complete = models.BooleanField(default=False)
# def __str__(self):
# return str(self.id) + " - " + str(self.size) + " por " + str(self.quantity)
def sub_total(self):
product_price = costo_de_los_productos.objects.filter(category = self.product.category.name,
product = self.product.name,
size=self.size,
quantity=self.quantity).values_list("price", flat=True)
# print(type(product_price))
return product_price
costo_de_los_productos model:
class costo_de_los_productos(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.IntegerField(default=30)
size = models.CharField(max_length=20, choices=TAMANIOS)
quantity = models.CharField(max_length=20, choices=CANTIDADES)
product model:
class Product(models.Model):
name = models.CharField(max_length=250, unique=False)
slug = models.SlugField(max_length=250, unique=False)
description = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
image = models.ImageField(upload_to='product', blank=True, null=True)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('name',)
verbose_name = 'product'
verbose_name_plural = 'products'
def get_url(self):
return reverse('shop:ProdDetail', args=[self.category.slug, self.slug])
def __str__(self):
return '{}'.format(self.name)
category model:
class Category(models.Model):
name = models.CharField(max_length=250, unique=True)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(blank=True, null=True)
image = models.ImageField(upload_to='category', blank=True, null=True)
video = EmbedVideoField(null=True, blank=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def get_url(self):
return reverse('shop:allCat', args=[self.slug])
def __str__(self):
return '{}'.format(self.name)
Image of "costo_de_los_productos" from Admin Panel:
UPDATE 1
Cannot print anything after the product_price query.
def sub_total(self):
print("Enters Subtotal")
print(self.product.category.name)
print(self.product.name)
print(self.size)
print(self.quantity)
product_price = costo_de_los_productos.objects.filter(category=self.product.category.name,
product=self.product.name,
size=self.size,
quantity=self.quantity).values_list("price", flat=True)[0]
print("Line after product_price query")
print(type(product_price))
return product_price
Hard coding the values doesn't return expected integer:
def sub_total(self):
print("Enters Subtotal")
print(self.product.category.name)
print(self.product.name)
print(self.size)
print(self.quantity)
product_price = costo_de_los_productos.objects.filter(category="Stickers",
product="Stickers transparentes",
size="5cm x 5cm",
quantity=300).values_list("price", flat=True)[0]
print("Line after product_price query")
print(type(product_price))
return product_price
prints results:
Enters Subtotal
Stickers
Stickers transparentes
5cm x 5cm
300

Auto Complete field in django

here are my models
class TimeSlots(models.Model):
start = models.TimeField(null=True, blank=True)
end = models.TimeField(null=True, blank=True)
class Meta:
ordering = ['start']
def __str__(self):
return '%s - %s' % (self.start, self.end)
class Event(models.Model):
event_date = models.DateField(null=False, blank=True)
start = models.OneToOneField(TimeSlots)
end = models.TimeField(null=True, blank=True)
available = models.BooleanField(default=True)
patient_name = models.CharField(max_length=60, null=True, blank=True)
phone_number = PhoneNumberField(blank=True, null=True)
stripePaymentId = models.CharField(max_length=150, null=True, blank=True)
stripePaid = models.BooleanField(null=False, blank=True, default=True)
key = models.UUIDField(primary_key=False, default=uuid.uuid4,
editable=False)
sites = models.ManyToManyField(Site, null=True, blank=True)
class Meta:
verbose_name = u'Scheduling'
verbose_name_plural = u'Scheduling'
def __unicode__(self):
return self.start
def get_absolute_url(self):
url = reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.pk])
return u'%s' % (url, str(self.start))
What I want is that end value of Event Model should be auto filled by the selected Timeslot
like when I choose a start value from timeslot for the event model the end value should automatically be filled
Ok I solved it by adding a clean function in my model
def clean(self):
self.end = self.start.end
It was that simple

Modify database in django

I am a beginner in django. Following is my Attendance Management App.
This is my models.py.
from django.db import models
class Subject(models.Model):
subject_name = models.CharField(max_length=20)
#attendance = models.ForeignKey(Attendance, on_delete =
models.DO_NOTHING)
attendance = models.IntegerField(default=0)
def __str__(self):
return self.subject_name
class Section(models.Model):
section_name = models.CharField(max_length=20)
subject = models.ManyToManyField(Subject)
def __str__(self):
return self.section_name
class Student(models.Model):
rollno = models.IntegerField()
name = models.CharField(max_length=20)
section = models.ForeignKey(Section, on_delete = models.DO_NOTHING,
default=0)
def __str__(self):
return str(self.rollno) + self.name
class Teacher(models.Model):
#teacher_name = models.CharField(max_length=20)
section = models.ForeignKey(Section, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
#section_name = models.CharField(max_length=10)
#subject_name = models.CharField(max_length=30)
def __str__(self):
return self.section.section_name+' '+self.subject.subject_name
class TeacherList(models.Model):
teacher_name = models.CharField(max_length=20)
teacher = models.ManyToManyField(Teacher)
def __str__(self):
return self.teacher_name
The line below is not working in views.py
student = models.Student.objects.get(rollno = sroll)
student.section.subject.get(subject_name = 'java').attendance += 1
student.save()
This view is called from a template when a button is clicked to add attendance of a student.
The attendance in above code is not modified. Please help me out.
You're saving the student, instead of the subject.
student = models.Student.objects.get(rollno = sroll)
subject = student.section.subject.get(subject_name='java')
subject.attendance += 1
subject.save()
Or, better, do the update directly in one go:
student.section.subject.filter(subject_name='java').update(attendance=F('attendance')+1)
and there's no need to save at all.

django models getting queryset

how to get status_updation and status_date respect to the order_number
class customer_database(models.Model):
customer_id = models.CharField(max_length=20, unique=True)
customer_name = models.CharField(max_length=20)
customer_email = models.EmailField()
def __str__(self):
return self.customer_id
class order_database(models.Model):
order_number = models.CharField(max_length=10, unique=True, primary_key=True)
order_timestamp = models.DateTimeField()
order_consignment_number = models.CharField(max_length=20)
order_customer = models.ForeignKey(customer_database, on_delete=models.CASCADE)
def __str__(self):
return self.order_number
class track_database(models.Model):
order_status = models.ForeignKey(order_database, on_delete=models.CASCADE)
status_updation = models.CharField(max_length=30)
status_timestamp = models.DateTimeField()
def __str__(self):
return self.status_updation
Try
query_order_number = '1234'
tracker = track_database.objects.filter(order_status.order_number = query_order_number)
print(tracker.status_updation)
print(tracker.status_timestamp)
Let me know if this doesn't work
Or you could go via the order number:
query_order_number = '1234'
order = order_database.objects.filter(order_number = query_order_number)
print(order.track_database.status_updation)
print(order.track_database.status_timestamp)