Django Simple Left Join - django

How can I display all related values from my model and display in template as one?
class DentalProcedures(models.Model):
id = models.AutoField(primary_key=True)
patient = models.ForeignKey(PatientInfo, on_delete=models.CASCADE, null=True, blank=True)
proc_date = models.DateField(null=True, blank=True)
proc_tooth_no = models.CharField('Tooth No./s', max_length=10, null=True, blank=True)
procedure = models.CharField('Procedure', max_length=200, null=True, blank=True)
amount_charged = models.IntegerField('Amount Charged', null=True, blank=True)
class DentalPayment(models.Model):
id = models.AutoField(primary_key=True)
procedureid = models.ForeignKey(DentalProcedures, on_delete=models.CASCADE, null=True, blank=True)
patient = models.ForeignKey(PatientInfo, on_delete=models.CASCADE, null=True, blank=True)
amount_paid = models.IntegerField('Amount Paid', null=True, blank=True)
date_paid = models.DateField(null=True, blank=True)
I want to display the patient summary of payment including the, procedure name, amount charged and payment details.
View
class DentalPaymentDetailView(DetailView):
context_object_name = "payment_detail"
model = PatientInfo
template_name = "patient/procedure_payment_detail.html"
def get_context_data(self, **kwargs):
context = super(DentalPaymentDetailView, self).get_context_data(**kwargs)
payment = DentalPayment.objects.filter(patient=self.kwargs['pk'])
context["payment"] = payment.DentalProcedures_set.all()
return context

If you have some logic to provide the patient_id, try this
context["payment"] = DentalPayment.objects.filter(patient_id=patient_id).values('procedureid__procedure', 'procedureid__amount_charged', 'amount_paid', 'date_paid')
to get total amount paid,
from django.db.models import Sum
total_amount = DentalPayment.objects.filter(patient_id=patient_id).aggregate(tota_amount_paid=Sum('amount_paid'))

Related

Sum in Django Rest Framework (DRF) Serializer

Excuse me devs, i wanna ask about how to count on drf serializer, i need codes that can serialized fields plant from table A and it relations with another table B with count of them "plants_active"
Here's my code:
# Models
class TablePlants(models.Model):
plant_id = models.CharField(primary_key=True, max_length=20, unique=True)
gateway = models.ForeignKey(
TableGatewayDevice, models.DO_NOTHING, blank=True, null=True)
name = models.CharField(max_length=150, blank=True, null=True)
date = models.DateField(blank=True, null=True)
contact_person = models.CharField(max_length=70, blank=True, null=True)
contact_email = models.CharField(max_length=50, blank=True, null=True)
contact_phone = models.CharField(max_length=30, blank=True, null=True)
plant_status = models.CharField(max_length=20, blank=True, null=True)
weather_status_code = models.ForeignKey(
TableAuxWeather, models.DO_NOTHING, db_column='weather_status_code', blank=True, null=True)
timezone = models.CharField(max_length=200, blank=True, null=True)
image = models.FileField(
upload_to='plants/', validators=[file_size, validate_file_extension], null=True, blank=True)
class Meta:
db_table = 'table_plants'
def __str__(self):
return 'TablePlants[id: {id}, name: {name}]'.format(
id=self.id, name=self.name)
class PVOwner(models.Model):
pv_owner_id = models.AutoField(primary_key=True)
company = models.ForeignKey(TableCompany, on_delete=CASCADE,
blank=True, null=True, related_name="pv_owner_company")
class Meta:
db_table = 'table_pv_owner'
class TableSitePlant(models.Model):
pv_owner = models.ForeignKey(
PVOwner, on_delete=CASCADE, blank=True, null=True, related_name="pv_site_owner_plant")
site_owner = models.ForeignKey(
SiteOwner, on_delete=CASCADE, blank=True, null=True, related_name="site_owner_plant")
plant = models.ForeignKey(TablePlants, on_delete=CASCADE,
blank=True, null=True, related_name="site_plant")
class Meta:
db_table = 'table_site_plant'
# Serializer
class MainMenuSerializer(serializers.ModelSerializer):
plants_active = serializers.IntegerField(source="plant")
class Meta:
model = TableSitePlant
fields = ['plants_active']
# Views
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter(plant__plant_status='offline')
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
What i expecting is i can count how many plants that have status online
You can use the get method to return response as you desired.
#permission_classes([AllowAny])
class OverviewPlantsActiveView(generics.RetrieveAPIView):
queryset = TableSitePlant.objects.all().filter()
serializer_class = OverviewPlantsActiveSerializer
lookup_field = 'pv_owner'
def get(self, request):
queryset = self.get_queryset().filter(plant__plant_status='online')
return Response({
"active_plants": queryset.count(),
})

How can I calculate discount fields from another table's fielsd

I have a model like this:
class InvoiceItem(models.Model):
book = models.ForeignKey(Book, on_delete=models.PROTECT)
invoice = models.ForeignKey(Invoice, on_delete=models.PROTECT, related_name='items')
title = models.CharField(max_length=100, null=True, blank=True)
price = models.IntegerField(null=True, blank=True)
discount = models.IntegerField(blank=True, default=0)
totalprice = models.IntegerField(null=True, blank=True)
count = models.IntegerField(null=True, blank=True)
and I want to calculate discount from book's discount table
How can I do it?
should I calculate it in models?
Here we can create property for override models fields like this (without override save() method)
class InvoiceItem(models.Model):
book = models.CharField(max_length=100)
invoice = models.PositiveIntegerField()
title = models.CharField(max_length=100, null=True, blank=True)
og_price = models.IntegerField(null=True, blank=True)
sell_price = models.IntegerField(null=True, blank=True)
discount = models.IntegerField(blank=True, default=0)
discounted_price = models.IntegerField(blank=True, default=0)
count = models.IntegerField(null=True, blank=True)
#property
def discounted_price(self):
return ((self.og_price*self.discount)/100)
#property
def sell_price(self):
return ((self.og_price - self.discounted_price))
with override save() method
class InvoiceItem(models.Model):
book = models.CharField(max_length=100)
invoice = models.PositiveIntegerField()
title = models.CharField(max_length=100, null=True, blank=True)
og_price = models.IntegerField(null=True, blank=True)
sell_price = models.IntegerField(null=True, blank=True)
discount = models.IntegerField(blank=True, default=0)
discounted_price = models.IntegerField(blank=True, default=0)
count = models.IntegerField(null=True, blank=True)
#property
def dis_price(self):
print((self.og_price*self.discount)/100)
return ((self.og_price*self.discount)/100)
#property
def selling_price(self):
print(self.og_price - self.dis_price)
return (self.og_price - self.dis_price)
def save(self, *args, **kwargs):
self.sell_price = self.selling_price
self.discounted_price = self.dis_price
super(InvoiceItem, self).save(*args, **kwargs)
Output
You need to fill only those fields
NOTE: here i changed two fields for data adding in database
book = models.CharField(max_length=100)
invoice = models.PositiveIntegerField()
If you want to calculate it before saving, or when it enter form admin panel or from any place you can override Save method in django model
Or you can calculate from view for example and insert it on saving
Save method example:
class MyModel(models.Model):
...
def save(self, *args, **kwargs):
here you can get field value and insert it in any field you want

Django, i can't put function form inside generic.UpdateView

I am making a app for one kindergarten in my city. I have kids model and payment model.
For updating kid I am using class based view generic UpdateView and for creating a payment i am using form and function view. I have not problems with payment form when I am using a different template but when I try to put it on the same template, payment form is not showing up and it's not working. Is it possible to have payment form on same template as UpdateView class ? I am using UpdateView class as profile page and I would like to have payment form on the same page. Please help. Thanks
models:
class Kids(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
city_birthday = models.CharField(max_length=100, blank=True, null=True)
custom_id = models.CharField(max_length=100 ,blank=True, null=True)
gender = models.CharField(max_length=100, choices=gender_choices, null=True, blank=True)
address = models.CharField(max_length=250, null=True, blank=True)
contact_phone = models.CharField(max_length=100, blank=True, null=True)
family_size = models.IntegerField(null=True, blank=True)
living_with = models.CharField(max_length=100, choices=living_choices, null=True, blank=True)
number_of_preschool_kids_in_family = models.IntegerField(null=True, blank=True)
kid_already_been_in_kindergarten = models.CharField(max_length=100, choices=preschool_choices,
null=True, blank=True ,default=False)
father_name = models.CharField(max_length=100, blank=True, null=True)
father_education_level = models.CharField(max_length=200, blank=True, null=True)
father_company = models.CharField(max_length=200, blank=True, null=True)
mother_name = models.CharField(max_length=100, blank=True, null=True)
mother_education_level = models.CharField(max_length=200, blank=True, null=True)
mother_company = models.CharField(max_length=200, blank=True, null=True)
parent_notes = models.CharField(max_length=500, blank=True, null=True)
program_choice = models.CharField(max_length=100, choices=kindergarten_program_choice, null=True,
blank=True)
def __str__(self):
return self.name
class Meta:
ordering = ['name']
class Payment(models.Model):
user = models.ForeignKey(Kids, on_delete=models.CASCADE, blank=True, null=True)
bank_paper_id = models.IntegerField(null=True, blank=True)
payment_date = models.CharField(max_length=100, null=True, blank=True)
paid = models.FloatField(null=True, blank=True)
need_to_pay = models.FloatField(null=True, blank=True)
notes = models.CharField(max_length=500, blank=True, null=True)
def __str__(self):
return self.user.name
views:
class UpdateKidView(UpdateView):
model = Kids
fields = '__all__'
template_name = 'vrtic/update_kid.html'
success_url = reverse_lazy('vrtic:kids')
def create_payment(request, pk):
kid = Kids.objects.get(id=pk)
payment_form = PaymentForm()
if request.method == 'POST':
payment_form = PaymentForm(request.POST)
if payment_form.is_valid():
payment = payment_form.save(commit=False)
payment.user = kid
payment_form.save()
return redirect('vrtic:kids')
context = {
'payment_form': payment_form,
'kid': kid
}
return render(request, 'vrtic/update_kid.html', context)
form:
class PaymentForm(forms.ModelForm):
class Meta:
model = Payment
fields = '__all__'
class UpdateKidView(UpdateView):
model = Kids
form_class = KidsForm
second_form_class = PaymentForm
template_name = 'vrtic/update_kid.html'
success_url = reverse_lazy('vrtic:kids')
def get_context_data(self, **kwargs):
context = super(UpdateKidView, self).get_context_data(**kwargs)
context['form'] = self.form_class(instance=self.get_object())
context['second_form'] = self.second_form_class()
return context
def post(self, request, **kwargs):
kids_form = self.form_class(request.POST, request.FILES, instance=self.get_object())
if kids_form.is_valid():
kid = kids_form.save()
payment_form = self.second_form_class(request.POST)
...
Not the happiest solution, but u got the idea, if need more help contact me to explain on Serbian, not sure how are the rules here for languages : )

Build Inline Formsets in Django Admin

So I am new to Django and I have been reading a lot of documentation to figure this out, I have a table called "Logs" that has logs of different positions (has FK of table "Position"), each position belongs to a department (has FK to table "Department") Check the image below :1
What I want to do is create a view just like this one :
2
and whenever you click on a department, it extends all the positions in it with their respective logs like this :
3
The Screenshots I have attached are my work in main app (or if you would like to call it front end), I wanted to replicate the same process in the Django Admin page, I keep seeing that I should use inlines but I can't seem to make it work, can someone help or put me in the right direction please ? much appreciated.
Here is what I have in my models.py :
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Site(models.Model):
site = models.CharField(max_length=200, blank=True, null=True)
totalHC = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.site
class Department(models.Model):
department = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.department
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE, null=True, default=Site(id="1").site)
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=2000, blank=True)
skills = models.CharField(max_length=2000, blank=True)
aoi = models.CharField(max_length=2000, blank=True)
github = models.CharField(max_length=200, blank=True)
linkedin = models.CharField(max_length=200, blank=True)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
class Grade(models.Model):
user = models.OneToOneField(Profile, on_delete=models.CASCADE)
ut1 = models.CharField(max_length=200, blank=True)
ut2 = models.CharField(max_length=200, blank=True)
ut3 = models.CharField(max_length=200, blank=True)
ut1p = models.ImageField(upload_to='plots', blank=True)
ut2p = models.ImageField(upload_to='plots', blank=True)
ut3p = models.ImageField(upload_to='plots', blank=True)
ut1pb = models.ImageField(upload_to='plots', blank=True)
ut2pb = models.ImageField(upload_to='plots', blank=True)
ut3pb = models.ImageField(upload_to='plots', blank=True)
ut12 = models.ImageField(upload_to='plots', blank=True)
ut13 = models.ImageField(upload_to='plots', blank=True)
ut23 = models.ImageField(upload_to='plots', blank=True)
class Section(models.Model):
class Meta:
verbose_name = 'Department'
verbose_name_plural = 'Departments'
section = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.section
class Question(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
section = models.ForeignKey(
"Section", on_delete=models.CASCADE, null=True, blank=True)
question_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return self.question_field
class Answer(models.Model):
class Meta:
verbose_name = 'Log'
verbose_name_plural = 'Logs'
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
answer_field = models.CharField(max_length=2000, blank=True, null=True)
def __str__(self):
return f"{self.user} answered {self.answer_field}"
class Position1(models.Model):
class Meta:
verbose_name = 'Position'
verbose_name_plural = 'Positions'
department = models.ForeignKey(
"Department", on_delete=models.CASCADE, null=True, blank=True)
position = models.CharField(max_length=200, blank=True)
jobID = models.CharField(max_length=200, blank=True)
class HCtype(models.TextChoices):
Staff = 'Staff', ('Staff')
IDL = 'IDL', ('IDL')
DL = 'DL', ('DL')
hctype = models.CharField(
max_length=5,
choices=HCtype.choices,
)
def __str__(self):
return self.position
class Log(models.Model):
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
INN = models.IntegerField(blank=True, null=True)
OUT = models.IntegerField(blank=True, null=True)
date = models.CharField(max_length=200, blank=True)
internal = models.IntegerField(default=0, null=True)
class SiteHasPosition(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
position = models.ForeignKey(Position1, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
standard = models.IntegerField(blank=True, null=True)
turn_over = models.IntegerField(blank=True, null=True)
class SiteHasDepartment(models.Model):
date = models.CharField(max_length=200, blank=True)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
value = models.IntegerField(blank=True, null=True)
class SiteKPIs(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)
date = models.CharField(max_length=200, blank=True)
staff = models.IntegerField(blank=True, null=True)
dl = models.IntegerField(blank=True, null=True)
idl = models.IntegerField(blank=True, null=True)
total_hc = models.IntegerField(blank=True, null=True)
total_in = models.IntegerField(blank=True, null=True)
total_out = models.IntegerField(blank=True, null=True)
staff_rate = models.IntegerField(blank=True, null=True)
dl_rate = models.IntegerField(blank=True, null=True)
idl_rate = models.IntegerField(blank=True, null=True)
Here is how I registred them in admin.py :
admin.site.register(Profile)
admin.site.register(Log)
admin.site.register(Position1)
admin.site.register(Department)
admin.site.register(Site)
admin.site.register(SiteHasDepartment)
admin.site.register(SiteHasPosition)
I would like to have a page in admin.py where I can select a site and for that specific site display :
all the departments(when you press a dpt all the positions will expand) for each position the standardHC, attributes from the Log table (that match that position,and that site) and attributes from SiteHasPosition( that match the site and that position)
I hope I made it clearer

Loop over django object

I have a model like this:
class Grn(models.Model):
owner = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='grn_owner')
warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE, related_name="grn_warehouse")
vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE, related_name="grn_vendor")
product1 = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='grn_product1')
product1_quantity = models.IntegerField(default=0)
product2 = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='grn_product2', blank=True, null=True)
product2_quantity = models.IntegerField(default=0, blank=True, null=True)
product3 = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='grn_product3', blank=True, null=True)
product3_quantity = models.IntegerField(default=0, blank=True, null=True)
product4 = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='grn_product4', blank=True, null=True)
product4_quantity = models.IntegerField(default=0, blank=True, null=True)
How can I loop over an object of this model?
I tried something like this:
class GRNFormView(CreateView):
model = Grn
template_name = 'GrnForm.html'
form_class = Grnform
def form_valid (self, form):
data = form.save(commit=False)
print("form.cleaned_data is ", form.cleaned_data)
data.owner = Employee.objects.filter(user = self.request.user.id)[0]
data.save()
print("data is", data)
for i in range(1,5):
if data.product(i):
print("product ", data.product(i))
else:
pass
How can I check if a product exists in an object and get its value ?
You can use getattr() to dynamically access the products.
for i in range(1,5):
if getattr(data, f"product{i}"):
print("product ", getattr(data, f"product{i}"))
else:
pass
You can also just use many-to-many relationship with:
products = models.ManyToManyField(Product)
And then access with:
data.products.all()