Store sum from views to database django - python

I am trying to store the total attendance of the student in percentage to the database without form.
the Views.py
def attStudName(request):
#to display each student name with their total mark in table form
students = MarkAtt.objects.values('studName__VMSAcc').annotate(mark=Sum('attendance'))
#to convert the total mark to percentage and save in FinalAtt table
mark = 0
mark += students.attendance
work = FinalAtt.objects.all()
for stud in students:
stud.mark = (stud.mark/1100) * 100
work.VMSAcc = students
work.finalMark = mark
work.save()
context = {
'students' : students
}
return render(request,'show-name.html',context)
MarkAtt Model:
class MarkAtt(models.Model):
studName = models.ForeignKey(Namelist,on_delete=models.SET_NULL,blank=True, null=True, default=None)
classGrp = models.ForeignKey(GroupInfo, on_delete=models.SET_NULL, null=True)
currentDate = models.DateField(default=now())
week = models.IntegerField(default=1)
attendance = models.IntegerField(default=100)
FinalAtt Model:
class FinalAtt(models.Model):
VMSAcc= models.ForeignKey(Namelist, on_delete=models.SET_NULL, null=True)
finalMark = models.DecimalField(max_digits=5, decimal_places=2)
The error i am getting is:
'QuerySet' object has no attribute 'attendance'
How do i resolve this and save the information i want successfully?

students is a QuerySet, so you can't do mark += students.attendance.
You most likely want to loop through them to calculate mark.

Related

Hey everyone I have problem in sorting queryset in Django

So, I am learning Django and trying to make a site similar to AirBNB.
I have models called lisitngs that has latitude and longitude stored in CharField. My model is as follows:
class Listing(models.Model):
class BathRoomType(models.TextChoices):
ATTACHED = 'Attached Bathroom'
COMMON = 'Shared Bathroom'
class RoomVentType(models.TextChoices):
AC = 'Air Conditioner'
NO_AC = 'No Air Conditioner'
class LisitngType(models.TextChoices):
ROOM = 'Room'
APARTEMENT = 'Apartement'
HOUSE = 'Full House'
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
city = models.ForeignKey(RoomLocation, on_delete=models.CASCADE)
exact_address = models.CharField(max_length=255)
lat = models.CharField(max_length=300, blank=False, null=False, default="0")
lng = models.CharField(max_length=300, blank=False, null=False, default="0")
description = models.TextField()
price = models.IntegerField()
listing_type = models.CharField(max_length=20, choices=LisitngType.choices, default=LisitngType.ROOM)
kitchen_available = models.BooleanField(default=False)
kitchen_description = models.TextField(null=True, blank=True)
bedrooms = models.IntegerField()
max_acomodation = models.IntegerField()
bathroom_type = models.CharField(max_length=20, choices=BathRoomType.choices, default=BathRoomType.ATTACHED)
no_bathrooms = models.IntegerField()
room_type = models.CharField(max_length=30, choices=RoomVentType.choices, default=RoomVentType.AC)
main_photo = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_1 = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_2 = models.ImageField(upload_to='room_images', default='default_room.jpg')
photo_3 = models.ImageField(upload_to='room_images', default='default_room.jpg')
is_published = models.BooleanField(default=False)
date_created = models.DateTimeField(default=timezone.now, editable=False)
slug = AutoSlugField(populate_from=['title', 'listing_type', 'bathroom_type', 'room_type'])
rating = models.IntegerField(default=5)
approved = models.BooleanField(default=False)
total_bookings = models.IntegerField(default=0)
def __str__(self):
return self.title
In my homepage what I want to do is show the listings which are nearby me.
For that I have a function named as near_places. This near_place function takes latitude and longitude after querying through the model Listing and returns the distance between the listing and current user accessing the homepage:
import geocoder
from haversine import haversine
def near_places(dest_lat, dest_lng):
g = geocoder.ip('me')
origin = tuple(g.latlng)
destination = (dest_lat, dest_lng)
distance = haversine(origin, destination)
return distance
My homepage function in views.py is as follows:
def home(request):
objects = Listing.objects.filter(is_published=True, approved=True)
for object in objects:
lat, lng = float(object.lat), float(object.lng)
object.distance = near_places(lat, lng)
return render(request, 'listings/home.html')
As you can see I have looped through the query set and for each data I have calculated the distance and appended in the queryset as distance. Now, I would like to only get 10 items that has lowest distance. How, can I do so.
I have tried to user object = objects.order_by('-distance')[:10] but it gives me error as
FieldError at /
Cannot resolve keyword 'distance' into field. Choices are: The_room_booked, approved, bathroom_type, bedrooms, city, city_id, date_created, description, exact_address, id, is_published, kitchen_available, kitchen_description, lat, listing_type, lng, main_photo, max_acomodation, no_bathrooms, photo_1, photo_2, photo_3, price, rating, reviewsandrating, room_type, slug, title, total_bookings, user, user_id
Any way that I can solve it?
Also it takes quite a time to calculate current distance using near_places() function as above. Any suggestions will be helpful.
Thank You
You can't do that, because your model doesn't have a distance field and there is no such DB column as well.
What you can do is either
add such field to your model - I don't recommend with your current logic as you will iterate over every instance and send sql request to update every row.
get your queryest, convert it to a list of dicts and then iterate over your list of dicts with your function adding the distance key to it. Then you can sort the list by the python sort function and pass it to the template.
Like:
objects = Listing.objects.filter(is_published=True, approved=True).values('lat', 'lng') # add fields that you need
for obj in objects:
obj['distance'] = near_places(obj['lat'], obj['lng'])
my_sorted_list = sorted(objects, key=lambda k: k['distance'])
Pass my_sorted_list to your template. You can add reverse=True arg to sorted function if you want another direction sorting.

Add quantity for every the same Client and Product in Django

I have 3 models, CustomerPurchaseOrderDetail, Customer and Product model, if Customer1 buy a product for example, Meat. it will save in CustomerPurchaseOrderDetail and if that Customer1 add another Meat Product, instead of adding another record to the database it will simply just add quantity.
this is my views.py
def batchaddtocart(request):
userID = request.POST.get("userID")
client = Customer(id=userID)
vegetables_id = request.POST.get("id")
v = Product(id=vegetables_id)
price = request.POST.get("price")
discount = request.POST.get("discount_price")
insert, create = CustomerPurchaseOrderDetail.objects.get_or_create(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount,
)
order_qs = CustomerPurchaseOrderDetail.objects.filter\
(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount
)
for order in order_qs:
if order.profile == client and order.products == v:
insert.quantity += 1
print(insert.quantity)
insert.save()
insert.save()
this is my models.py
class CustomerPurchaseOrderDetail(models.Model):
profile = models.ForeignKey(Customer,
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name="Client Account")
products = models.ForeignKey(Product,
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name="Product")
quantity = models.IntegerField(max_length=500, null=True, blank=True, default=1)
class Product(models.Model):
product = models.CharField(max_length=500)
class Customer(models.Model):
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
firstname = models.CharField(max_length=500, blank=True)
lastname = models.CharField(max_length=500, blank=True)
contactNumber = models.CharField(max_length=500, blank=True)
email = models.CharField(max_length=500, blank=True)
I did not encounter an error but the functionality I wanted did not work. it does not add additional quantity even if the same product is added to the list purchased by Customer1.
the problem is in following lines client = Customer(id=userID) and v = Product(id=vegetables_id) every time your function is called you are creating new customer and product objects instead of using existing objects is your database. replace them with client,created = Customer.objects.get_or_create(id=userID) and same for product v,v_created = Product.objects.get_or_create(id=vegetables_id)
When you use get_or_create method, it will create a new entry whenever at least one parameter is different enough to did not match any registered value. So, if you pass the quantity parameter equals 1, it always will create a new entry when quantity is 2+, for instance.
You should filter first with only the "fixed" parameters and create a new entry if you get nothing. Otherwise, just increment quantity.
Something like this:
order = None
order_qs = CustomerPurchaseOrderDetail.objects.filter\
(
profile=client,
products=v,
unitprice=price,
discounted_amount=discount,
discounted_unitprice=discount
)
if not order_qs:
order = CustomerPurchaseOrderDetail.objects.create(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount,
)
else:
for order in order_qs:
if order.profile == client and order.products == v:
# NOTE: Please, note if you need to check your other parameters too (unityprice, discounted....)
order.quantity += 1
print(order.quantity)
order.save()

Is there a way to filter data when passing it in ModelForm and how can we edit them?

I'm creating a site to register students. So basically it is divided into 3 parts
1. A student register model which take the name, fathername, etc of student.
2. A student fee model which use foreignkey to get register student.
3. ModelForm for showing student fee model to enter data.
Now the problem if I want to fill a student fee of class 1 it shows all the student of other classes, but I want the student filter according to their classes and their name show and in front of them editable fee and pending fee form.
By some reach I got to know about ModelForm instance I wrote code for automatically add register students to student fee.
def student_fee(request):
# add a selection field to a variable for filtering student_class below this.
students = StudentRegister.objects.filter(student_class="1")
....
for x in students:
if not StudentFee.objects.filter(student=x):
StudentFee.objects.create(student=x, fee=0, pending_fee=0)
But for instance I have to know primary key of every student I can loop through them but it only get the last element.
models.py
class StudentRegister(models.Model):
student_image = models.ImageField(upload_to="register_student", blank=True)
student_class = models.CharField(max_length=2, choices=STUDENT_CLASS, default="1")
mobile_number = models.CharField(max_length=50)
student_name = models.CharField(max_length=50)
father_name = models.CharField(max_length=50)
mother_name = models.CharField(max_length=50)
address = models.CharField(max_length=200)
student_fee = models.CharField(max_length=10, default="0")
Date_Of_Birth = models.DateField(auto_now=False)
admission_fee = models.CharField(max_length=10)
Admission_date = models.DateField(auto_now=False)
adhaar_no = models.CharField(max_length=100)
def __str__(self):
return "%s class: %s" % (self.student_name, self.student_class)
class StudentFee(models.Model):
student = models.ForeignKey(StudentRegister, on_delete=models.CASCADE)
fee = models.CharField(max_length=20)
pending_fee = models.CharField(max_length=20)
def __str__(self):
return "%s " % (self.student)
forms.py
class StudentFeeForm(forms.ModelForm):
class Meta:
model = StudentFee
fields = '__all__'
views.py(its messy sorry)
def student_fee(request):
# add a selection field to a variable for filtering student_class below this.
students = StudentRegister.objects.filter(student_class="1")
real = StudentFee.objects.all()
# student_form = StudentFeeForm(request.POST or None)
student_form = StudentFeeForm(request.POST)#, instance=students)
# print(dir(students))
q = (students.get(pk=1))
global list_student_pk
list_student_pk = []
for x in students:
list_student_pk.append(x.pk)
student_get_instance = StudentFeeForm(instance=q)
# print(student_get_instance)
# This thing done don't touch----------------------------------
for x in students:
if not StudentFee.objects.filter(student=x):
StudentFee.objects.create(student=x, fee=0, pending_fee=0)
if request.method == "POST":
if student_form.is_valid():
pass # this thing will done after the form problem solved.
# till here ==========================================================
return render(request, "student_fee_home.html", {"students": students, "real":real, "student_form":student_form, "list_student_pk":list_student_pk, "student_get_instance":student_get_instance})
I want that modelforms filter according to class.
Then the student fee model which already having register student(student name, fee, pending fee) can edit. So that it shows the student name and right in front of him a editable fee form and a pending fee form.
It is working right now like this showing all student of all classes, but I want that students name will show instead of selection field. In my knowledge only option to display names of student display names direct from models then use a form to take input of fee and pending fee then create it in models.
djang0-filter will help you for filtering
pip install django-filter
Model.py
class Dispatcher(models.Model):
_safedelete_policy = SOFT_DELETE
Individual = 'Individual'
Company = 'Company'
TYPES = [
(Individual, 'Individual'),
(Company, 'Company')
]
type = models.CharField(max_length=255,
choices=TYPES,
default=Individual)
Views.py
class DispatcherViewSet(viewsets.ModelViewSet):
queryset = Dispatcher.objects.all()
serializer_class = DispatcherSerializer
filter_backends = (DjangoFilterBackend,)
filterset_fields = ['type']

Django Cannot assign "'Pizza'": "Order.Food_Name" must be a "Foods" instance

Hello Guys I am working on a restaurant project which allow user to select food item and book an order but i am getting this error as i try to book an order
"Django Cannot assign "'Pizza'": "Order.Food_Name" must be a "Foods" instance."
I am using drop down menu to select food items i am using django version 2.1.5 . Please Help
views.py
def place_order(request):
name = request.POST["user"]
food_items = request.POST['food_item']
qty = request.POST['qty']
rating = request.POST['ratings']
price = Foods.Food_Price
order = Order(Date=datetime.date, Name_of_Person=name,Food_Name=food_items, Qty=qty, Total=price, Ratings=rating)
order.save()
return render(request, "index.html")
model.py
from django.db import models
class Foods(models.Model):
Food_Number = models.IntegerField(null=False,)
Food_Name = models.CharField(max_length=30, primary_key=True, null=False)
Food_Qty = models.CharField(max_length=10)
Food_Price = models.IntegerField()
def __str__(self):
return f"{self.Food_Number} - {self.Food_Name} {self.Food_Price}"
class Order(models.Model):
Order_id = models.AutoField(null=False, primary_key=True)
Date = models.DateField()
Name_of_Person = models.CharField(null=False, max_length=40)
Food_Name = models.ForeignKey(Foods, on_delete=models.CASCADE)
Qty = models.CharField(max_length=10)
Total = models.IntegerField()
Ratings = models.IntegerField()
def __str__(self):
return f"{self.Order_id} - {self.Name_of_Person} |{self.Food_Name} |{self.Total}"
What can i do solve this error
Problem is in your Order model Food_Name is foreign-key field. So you need to assign model-instance which is Food in this case to this field. But you are assigning food_items = request.POST['food_item'] which is suppose to be food_name string i guess. That is why this error raise. I don't think your model is properly design. Food_Name is not an unique id field in Food model rather in your Order table you would like to have Food not Food_name.

Django - Cannot resolve keyword 'total' into field

Am having a model called Cart which contains the following fields
class Cart(models.Model):
client = models.ForeignKey(User, null=True)
description = models.CharField(max_length = 100)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField()
ordered = models.BooleanField(default=False)
created_on = models.DateTimeField(auto_now_add = True)
def __str__(self):
return self.description
def total(self):
return self.price * self.quantity
I wish to get the total amount per item in django views.
Here is the cart views
def cart(request): # Client View
request_user = request.user
item = Cart.objects.filter(client=request_user, ordered=False).values('total')
print "item ", item
If i print item, i get
Cannot resolve keyword 'total' into field. Choices are: client, client_id, created_on, description, docfile, id, order_id, ordered, price, quantity
But if i print item when .value('price'), i get result.
Is there a way to get value of total amount
Why don't you try this? ie, access the total method through Cart instance.
[i.total() for i in Cart.objects.filter(client=request_user, ordered=False)]
You need to create total function which will take price of each object you filter on the basis of client OR you can right query as follows:
total = 0
for i in Cart.objects.filter(client=request_user, ordered=False).all():
#print i.price
total = total+i.price
You can't write values('total'), as you don't have any field in your card model as total.

Categories