I need to find maximum score of user id with the maximum quiz score in a category.
My Model:
class QuizCat(models.Model):
cid = models.IntegerField(unique=True)
c_name = models.CharField(max_length=200)
class Quiz(models.Model):
Qid = models.IntegerField()
cat_id = models.ForeignKey(QuizCat, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
class UserDetails(models.Model):
user_id = models.IntegerField()
Qid = models.ForeignKey(Quiz, on_delete=models.CASCADE)
score = models.IntegerField()
I tried:
category_id = request.GET.get('category_id')
result = UserDetails.objects.all().values('user_id').annotate(score=Sum('score')).filter(Qid__cat_id=category_id)
But the above did not work.
Instead of Sum, use Max:
result = UserDetails.objects.filter(Qid__cat_id=category_id).values('user_id').annotate(score=Max('score'))
Related
I have a Attendance model
class Attendance(models.Model):
employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
date = models.DateField()
day = models.CharField(max_length=10)
in_time = models.CharField(max_length=5)
out_time = models.CharField(max_length=5)
Here is the Employee model
class Employee(models.Model):
emp_id = models.CharField(max_length=10,primary_key=True)
emp_type = models.CharField(max_length=50)
name = models.CharField(max_length=100)
epf_no = models.CharField(max_length=10)
nic_no = models.CharField(max_length=15)
appoinment_date = models.DateField()
termination_date = models.DateField()
address = models.CharField(max_length=50)
mobile_no = models.CharField(max_length=15)
email = models.EmailField(max_length=50)
bank_name = models.CharField(max_length=50)
bank_branch = models.CharField(max_length=20)
bank_acc_name = models.CharField(max_length=20)
bank_acc_no = models.CharField(max_length=15)
active_status = models.BooleanField(default=True)
I'm getting data from Attendance model
attendance_record = Attendance.objects.filter(date = date).values()
Here for the employee attribute I'm automatically getting the emp_id field.But I want to get the name field as well
How to do it.?
You can access the name through the employee relation:
attendance_record.employee.name
If you want the name in the attendance_record queryset, you can use F('') expressions.
from django.db.models import Avg, Case, Count, F
Attendance.objects.filter(date=date).annotate(name=F('employee__name')).values()
I have 2 models
class Movie(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=100)
vote_count = models.IntegerField()
def __str__(self):
return self.title
class Watchlist(models.Model):
userid = models.IntegerField()
movie_id = models.ForeignKey(Movie, on_delete=models.CASCADE)
rating = models.IntegerField()
def __int__(self):
return self.userid
what will be query to fetch highest watched movie
from django.db.models import Count
# the most watched Movie instance
the_most_watched_movie = Movie.objects.annotate(count=Count('watchlist')).order_by('-count').first()
Also it could be done via Watchlist if you would need it for some reason
watchlist = Watchlist.objects.annotate(count=Count('userid')).values('movie_id', 'count').order_by('-count').first()
movie_id = watchlist['movie_id'] # the most watched movie id
# the most watched Movie instance
the_most_watched_movie = Movie.objects.get(id=movie_id)
I want to access the records in mysql view using django filter but it throws an error
class PartnerPayBillSummaryDetails(models.Model):
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = '66_1_partner_pay_bill_ageing_dtl'
try:
p = PartnerPayBillSummaryDetails.objects.all()
print(p)
except Exception as e:
print(e)
Error:
OperationalError: (1054, "Unknown column '66_1_partner_pay_bill_ageing_dtl.id' in 'field list'")
I figured out the answer
it requires a filed as a primary key. I solve this by adding
"primary_key=True" in invoice_id
invoice_id = models.IntegerField(primary_key=True)
In my opinion it is looking for a primary key called 'id' (by default if you don't define). Also your db_table name in meta class is starting with a number. Not sure it will allow that. I am away from computer to test it out but based on guess, I have two solutions for you. Please try them in that order. All I have done is change your model class in both the solutions.
class PartnerPayBillSummaryDetails(models.Model):
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = 'partner_pay_bill_ageing_dtl_66_1'
Solution 2
class PartnerPayBillSummaryDetails(models.Model):
id = models.AutoField(primary_key=True)
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = 'partner_pay_bill_ageing_dtl_66_1'
Please let me know if there is still some error.
You have to add primary key to the model.
id = models.AutoField(primary_key=True)
or make any column the primary key like:
invoice_id = models.IntegerField(primary_key=True)
Consider the following database model:
class User:
id = models.BigAutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Restaurant:
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=50)
class Rating:
id = models.BigAutoField(primary_key=True)
by_user = models.ForeignKey(to='User',
on_delete=models.PROTECT,
related_name='written_ratings')
for_restaurant = models.ForeignKey(to='Restaurant',
on_delete=models.PROTECT,
related_name='received_ratings')
score = models.SmallIntegerField()
# make sure only one vote per user per restaurant
class Meta:
unique_together = ('by_user', 'for_restaurant')
For a given User, we can obtain a list of Restaurant that we have not yet rated by performing the following query (that I have learned from my last post)
eligible_restaurants = Restaurant.objects.exclude(rating__by_user_id=my_id)
But what happens when the Ratings don't point directly at the Restaurants - but rather at an intermediate Profile object?
class User:
id = models.BigAutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Restaurant:
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=50)
current_profile = models.OneToOneField(to='Profile',
on_delete=models.PROTECT,
related_name='+')
# the `+` means to not generate a related name
class Profile:
# this is here acting as an intermediate between
# `Restaurant` and `Rating` so that we can keep track
# of all reviews - deleting/remaking would simply be
# creating a new `Profile` and setting the `Restaurant`
# to point to it instead - the old one will act as a
# historical record
id = models.BigAutoField(primary_key=True)
by_restaurant = models.ForeignKey(to='Restaurant',
on_delete=models.PROTECT,
related_name='written_profiles')
picture_url = models.CharField(max_length=500)
picture_desc = models.CharField(max_length=500)
class Rating:
id = models.BigAutoField(primary_key=True)
by_user = models.ForeignKey(to='User',
on_delete=models.PROTECT,
related_name='written_ratings')
for_profile = models.ForeignKey(to='Profile',
on_delete=models.PROTECT,
related_name='received_ratings')
score = models.SmallIntegerField()
# make sure only one vote per user per restaurant
class Meta:
unique_together = ('by_user', 'for_profile')
How would I query for eligible restaurants now?
You could filter them starting with restaurants
restaurant_ids = Rating.objects.filter(by_user=user).values_list('for_profile__by_restaurant', flat=True).distinct()
eligible_restaurants = Restaurant.objects.exclude(id__in=restaurant_ids)
Note: this will generate only one query because django's querysets are lazy.
models.py
class Custom_user_model(User):
daily_target = models.IntegerField()
monthly_target = models.IntegerField()
yearly_target = models.IntegerField()
weekly_target = models.IntegerField()
call_target = models.IntegerField()
email_target = models.IntegerField()
meeting_target = models.IntegerField()
added_under = models.IntegerField()
profile_pic = models.TextField()
doj = models.DateTimeField(default='')
location_id = models.IntegerField()
locked = models.BooleanField()
default_currency = models.IntegerField()
date_change_permission = models.BooleanField()
deal_back_log = models.BooleanField()
created_date=models.DateTimeField(auto_now_add=True)
role_id=models.ForeignKey('user_Roles')
profile_pic = models.FileField(upload_to='.')
objects = UserManager()
class Deal(models.Model):
a_choices = ((0,'yes'),(1,'no'))
approved = models.IntegerField(choices=a_choices,default=1)
user_id = models.ForeignKey('Custom_user_model')
company_id = models.IntegerField()
contact_id = models.IntegerField()
deal_title=models.CharField(max_length=200)
deal_value = models.CharField(max_length=20)
currency_id = models.IntegerField()
process_id = models.IntegerField()
expected_close_date = models.DateField(default='')
closed_date = models.DateField()
deal_milestone=models.IntegerField()
created=models.DateTimeField(auto_now_add=True)
last_modified=models.DateTimeField(auto_now_add=True)
s_choices = ((0,'active'),(1,'won'),(2,'junk'),(3,'lost'))
status = models.IntegerField(choices=a_choices,default=0)
type = models.CharField(max_length=50, default='deal')
class user_Roles(models.Model):
code = models.CharField(max_length=20)
description = models.CharField(max_length=30)
permitted_menus = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
views.py
Here, i wrote the code to get columns from three models. But
Deal.objects.filter(user_id__role_id_id=1).select_related() returned nothing and Deal.objects.filter(user_id__role_id_id=1).select_related().values() returned the fields from deal model only. It shows 'no fields error', when specifying relationship as values('Custom_user_model__doj').How can i select fields from multiple models?
def get_all_normal_users(request,start_date=None,end_date=None):
query = Deal.objects.filter(user_id__role_id_id=1).select_related().values()
start_date_range = (
# The start_date with the minimum possible time
datetime.datetime.combine(start_date, datetime.time.min),
# The start_date with the maximum possible time
datetime.datetime.combine(end_date, datetime.time.max)
)
query = query.filter(created__range=start_date_range).values()
data_dict = ValuesQuerySetToDict(query)
data_json = json.dumps(data_dict)
return json_response({'status':data_json})
If you want to select related values you have to specify all parameters you want in values(). Otherwise you will get only the foreignkey to your user model. Try adding the values you want from your user model with __:
query = query.filter(created__range=start_date_range).values('approved', ..., 'user_id__daily_target', 'user_id__username')
Btw if you are creating an API you should have a look at django-rest-framework
try this,
Deal.objects.filter(user_id__role_id_id=1, created__range=start_date_range).select_related('user_id').values()
or specify required fields as parameters to values().