perfoming right join with django queryset - django

I just need to apply right join with query set.
vdata = (VisVisitData.objects.
.select_related('vpvalue','vparameter')
.filter(vpvalue__vparameter=9,)
.values(name=F('vpvalue__parameter_value'),
visit_day=F('visit__visit_day'),
question=F('vparameter'),
value_id=F('vpvalue'))
.annotate(data=Count('vpvalue_id'))
.order_by('visit__visit_day'))
above code generate following join statement.
FROM vis_visit_data INNER JOIN vis_visit_parameter_values ON
(vis_visit_data.vpvalue_id =
vis_visit_parameter_values.vpvalue_id) LEFT OUTER JOIN
vis_visits ON (vis_visit_data.visit_id =
vis_visits.visit_id)
But I need to do right join instead of Inner Join with vis_visit_parameter_values and vis_visit_data table. below is the snapshot of sql in which I want to make changes.
INNER JOIN vis_visit_parameter_values ON
(vis_visit_data.vpvalue_id =
vis_visit_parameter_values.vpvalue_id)
Model classes (using these 3 models in query set
class VisVisitParameterValues(models.Model):
vpvalue_id = models.IntegerField(primary_key=True)
vparameter = models.ForeignKey('VisVisitParameters', models.DO_NOTHING,related_name='values')
parameter_value = models.TextField(blank=True, null=True)
class VisVisits(models.Model):
visit_id = models.IntegerField(primary_key=True,auto_created=True)
app_local_id = models.IntegerField(blank=True, null=True)
visit_day = models.IntegerField(blank=True, null=True,db_column='visit_no')
class VisVisitData(models.Model):
vdata_id = models.IntegerField(primary_key=True,auto_created=True)
app_local_id = models.IntegerField(blank=True, null=True)
visit = models.ForeignKey('VisVisits', models.DO_NOTHING, blank=True, null=True, related_name='data')
vparameter = models.ForeignKey('VisVisitParameters', models.DO_NOTHING, blank=True, null=True,related_name='parameters')
vpvalue = models.ForeignKey('VisVisitParameterValues', models.DO_NOTHING, blank=True, null=True,related_name='parameters_values')

Have you tried using:
.filter(Q(vpvalue__isnull=True) | Q(vpvalue__vparameter=9))

Related

Django Filter and Sum Value depends on different model

_Hi, guys! I'm trying to sum times for users for each Month(Mission), like this:
times = goal.time_set.filter(day__year=today.year, day__month=today.month)
Then I will sum:
for time in times:
total_min[member_number] = total_min[member_number] + time.value
But it calculates for current Month(Mission).
I want to calculate time depends on object model Mission. Model Mission:
class Mission(models.Model):
name = models.CharField(max_length=200, default='')
description = models.TextField(default='')
add_info = models.TextField(default='', blank=True)
theme = models.ImageField(upload_to='themes/', default='themes/default.png')
date_created = models.DateTimeField(null=True)
date_finished = models.DateTimeField(null=True, blank=True)
Like this I think:
times = goal.time_set.filter(day__year=mission.date_created.year, day__month=mission.month_created.month)
How can I achieve it?
upd. Goal model:
class Goal(models.Model):
STATUS = (
('in progress', 'in progress'),
('completed', 'completed'),
('failed', 'failed')
)
id_ninja = models.ForeignKey(Ninja, null=True, on_delete=models.SET_NULL)
id_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=150, default='')
description = models.TextField(default='')
date_created = models.DateTimeField(null=True)
status = models.CharField(max_length=20, choices=STATUS, default='in progress')
I solved the problem in my way.
mission_year = mission.date_created.strftime('%Y')
mission_month = mission.date_created.strftime('%m')
times = goal.time_set.filter(day__year__gte=mission_year, day__month__gte=mission_month)

Accessing model through other model via django queryset

I need to access columns in particular table through foreign keys in another table. I wrote it in SQL, but how it will be in queryset language?
This is models.py
class carModel(models.Model):
id_car_model = models.IntegerField(primary_key=True)
id_car_mark = models.ForeignKey(carMark,on_delete=models.CASCADE)
name = models.CharField(max_length=255)
date_create = models.IntegerField(max_length=10,null=True)
date_update = models.IntegerField(max_length=10,null=True)
id_car_type = models.ForeignKey(carType,on_delete=models.CASCADE)
name_rus = models.CharField(max_length=255,null=True)
class CarParts(models.Model):
id_catalog = models.IntegerField(primary_key=True)
manufacturer = models.CharField(max_length=200,blank=True, null=True)
vendor_code = models.IntegerField(blank=True, null=True)
subgroup = models.CharField(max_length=200,blank=True, null=True)
title = models.CharField(max_length=200,blank=True, null=True)
side = models.CharField(max_length=200,blank=True, null=True)
description = models.CharField(max_length=200,blank=True, null=True)
model = models.CharField(max_length=200,blank=True, null=True)
trade_mark = models.CharField(max_length=200,blank=True, null=True)
original_number = models.CharField(max_length=200,blank=True, null=True)
request = models.CharField(max_length=200,blank=True, null=True)
price = models.IntegerField(blank=True, null=True)
sum = models.IntegerField(blank=True, null=True)
availability = models.CharField(max_length=200,blank=True, null=True)
class interimTable(models.Model):
id_interim = models.IntegerField(primary_key=True)
description = models.CharField(max_length=100,null=True)
id_catalog=models.ForeignKey(CarParts, on_delete=models.CASCADE)
id_car_model = models.ForeignKey(carModel,on_delete=models.CASCADE)
This is SQL request, that is successful. I need same thing, but like querySet, to use it in further code.
Select title,side,price
from carinfo_carparts,carinfo_interimtable,carinfo_carmodel
where id_catalog = carinfo_interimtable.id_catalog_id
and carinfo_carmodel.id_car_model = carinfo_interimtable.id_car_model_id
and carinfo_carmodel.name='Civic';
this is the result
Try this,
CarParts.objects.filter(interimtable__id_car_model__name='Civic').values('title', 'side', 'price')

Error computing aggregate over related model in Django

I have the following models:
class Contest(models.Model):
id_contest = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=False)
class Registration(models.Model):
id_registration = models.AutoField(primary_key=True)
team = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
related_name='registrations',
related_query_name='registration')
contest = models.ForeignKey(
Contest,
on_delete=models.DO_NOTHING,
related_name='registrations',
related_query_name='registration')
created_at = models.DateTimeField(null=True)
confirmed_at = models.DateTimeField(null=True)
class Submission(models.Model):
id_submission = models.AutoField(primary_key=True)
team = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
related_name='submissions',
related_query_name='submission')
contest = models.ForeignKey(
Contest,
on_delete=models.DO_NOTHING,
related_name='submissions',
related_query_name='submission')
submitted_at = models.DateTimeField(null=True)
is_valid = models.NullBooleanField()
public_score = models.FloatField(null=True)
And I'm working on a leaderboard query (PostgreSQL) like:
select
r.team_id,
max(t.username) as team_name,
count(s.team_id) as num_submissions,
min(s.public_score) as score,
max(s.submitted_at) as last_submission,
max(r.confirmed_at) as confirmation
from api_registration r
left join auth_user t on (r.team_id = t.id)
left join api_submission s on (r.contest_id = s.contest_id and s.team_id = t.id and s.is_valid = TRUE)
where r.contest_id = 1
group by r.team_id
order by score ASC, last_submission DESC;
Which returns the results I want.
However, when translating into Django QuerySet operations, the closest I've
come is:
leaderboard = Registration.objects \
.filter(contest=contest, contest__submission__is_valid=True) \
.annotate(team_name=Max('team__username'),
num_submissions=Count('team__submission'),
score=Min('contest__submission__public_score'),
last_submission=Max('contest__submission__submitted_at'),
confirmation=Max('confirmed_at')) \
.order_by('score', '-last_submission')
which generates the query:
SELECT
"api_registration"."id_registration",
"api_registration"."team_id",
"api_registration"."contest_id",
"api_registration"."created_at",
"api_registration"."confirmed_at",
MAX("api_registration"."confirmed_at") AS "confirmation",
MAX("api_submission"."submitted_at") AS "last_submission",
MAX("auth_user"."username") AS "team_name",
MAX("api_submission"."public_score") AS "score",
COUNT(T5."id_submission") AS "num_submissions"
FROM "api_registration" INNER JOIN "api_contest" ON ("api_registration"."contest_id" = "api_contest"."id_contest")
INNER JOIN "api_submission" ON ("api_contest"."id_contest" = "api_submission"."contest_id")
INNER JOIN "auth_user" ON ("api_registration"."team_id" = "auth_user"."id")
LEFT OUTER JOIN "api_submission" T5 ON ("auth_user"."id" = T5."team_id")
WHERE ("api_registration"."contest_id" = 1
AND "api_submission"."is_valid" = True)
GROUP BY "api_registration"."id_registration"
ORDER BY "score" ASC, "last_submission" DESC;
And doesn't properly compute the correct number of submissions per team.
Any help on how to define the Django QuerySet operations to obtain correct results?
Try change this:num_submissions=Count('team__submission'), for num_submissions=Count('team_id'),.
This is to group according to the team_id of the table registration.

Compare fields of same model

I have this model:
#Model for match result forecast
class ResultForecast(models.Model):
user = models.ForeignKey(User)
created_date = models.DateTimeField('match date', blank=True, null=True)
home_goals = models.DecimalField(max_digits=5, decimal_places=0, blank=True, null=True)
away_goals = models.DecimalField(max_digits=5, decimal_places=0, blank=True, null=True)
match = models.ForeignKey(Match, related_name='forecasted_match')
So I wanna get the objects where de home_goals are greater than the away goals and vice versa, I use this:
total_forecast = ResultForecast.objects.filter(match=match).count()
home_trend = ResultForecast.objects.filter(match=match, home_goals__gt=F('away_goals'))
away_trend = ResultForecast.objects.filter(match=match, away_goals__gt=F('home_goals'))
But it does not work
I am wondering if match should actually be match__exact? Have you tried the following to see if it makes any difference? I also prefer to use the Q class. https://docs.djangoproject.com/en/1.7/ref/models/queries/
from django.db.models import Q
home_trend = ResultForecast.objects.filter(
Q(match__exact=match) &
Q(home_goals__gt=F('away_goals')))
away_trend = ResultForecast.objects.filter(
Q(match__exact=match) &
Q(away_goals__gt=F('home_goals')))

how to filter values_list in django

class Office(models.Model):
person = models.ForeignKey(Person, verbose_name="Person")
department = models.ForeignKey(Department, verbose_name="Department")
office_desc = models.CharField('Office', max_length=100,unique=True)
office_acronym = models.CharField('Office Acronym', max_length=20,blank=True,help_text="Add acronym if any, not required")
location = models.CharField('Location',max_length=100,blank=True)
trunkline = models.CharField('Trunk Line',max_length=30,blank=True)
directline = models.CharField('Direct Line',max_length=30,blank=True)
localnumber = models.CharField('Local Number',max_length=30,blank=True)
telefax = models.CharField('Telefax',max_length=30,blank=True)
active = models.BooleanField('Active',default=True)
class Department(models.Model):
department_desc = models.CharField('Department', max_length=100,unique=True)
department_acronym = models.CharField('Department Acronym', max_length=20,blank=True,help_text="Add acronym if any, not required")
active = models.BooleanField('Active',default=True)
class Person(models.Model):
GENDER = (
('M','Male'),
('F','Female'),
)
first_name = models.CharField("First Name", max_length=100)
last_name = models.CharField("Last Name",max_length=100)
middle_name = models.CharField("Middle Name", max_length=100, blank=True)
salutation = models.ForeignKey(Salutation, verbose_name="Salutation", null=True, blank=True) #
suffix_name = models.ManyToManyField(SuffixName, verbose_name="Suffix Name",null=True, blank=True) #
job_title = models.ManyToManyField(JobTitle, verbose_name="Job Title",null=True, blank=True) #
gender = models.CharField(max_length=1, choices=GENDER,default='Male')
birthdate = models.DateField('Birthdate',null=True,blank=True)
image = models.ImageField('Image',upload_to='persons',blank=True)
email = models.EmailField('Email',blank=True)
street = models.CharField('Street',max_length=100, blank=True)
brgy = models.CharField('Barangay',max_length=100, blank=True)
town_city = models.CharField('Town/City',max_length=100, blank=True)
zip_code = models.IntegerField('ZIP Code',null=True, blank=True)
department = models.ManyToManyField(Department, verbose_name="Department",null=True, blank=True) #
office = models.ManyToManyField(Office, verbose_name="Office", null=True, blank=True) #
sql_query
select pd.department_desc, pp.last_name, o.office_desc from person_person as pp
INNER JOIN person_person_department as ppd on pp.id = ppd.person_id
INNER JOIN person_department as pd on pd.id = ppd.id
INNER JOIN person_office as o on o.department_id = pd.id
where pd.department_desc = 'Executive'
views code:
per = Person.objects
qry_name = per.values_list('salutation__salutation_desc','first_name','middle_name','last_name', 'office__office_desc', 'office__location','office__localnumber','office__trunkline','office__directline','office__telefax').filter(department__department_desc='Executive')
Result: query result includes person with different department
Expected result: only person with Executive department
If I query directly from the database I get the correct result but when I translate the query into django code it's returning different queryset. Query returns ok if certain person has a single office but if a person has multiple office thats where the inconsistency starts .Query returns list with different description other than what was specified. Am I doing the translation of the query to python right?
A closer representation of the sql query would be:
from django.db.models import F
qry_name = Person.objects.filter(
department__department_desc='Executive',
office__department=F('department')
).values_list(<..FIELDS..>)
Let know if this works.