Django: calculating multiple values of over a set of children - django

I'm writing the management interface for a competition, and have the following models:
class Heat(models.Model):
current_heat = models.IntegerField()
track = models.ForeignKey(Track, on_delete=models.PROTECT)
previous_heat = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
start_date = models.DateTimeField('Start Date', default=timezone.now)
end_date = models.DateTimeField('End Date', null=True, blank=True)
class Game(models.Model):
heat = models.ManyToManyField(Heat)
format = models.TextField(max_length=20, default="V")
player1 = models.ForeignKey(User, on_delete=models.PROTECT, related_name='player1')
player2 = models.ForeignKey(User, on_delete=models.PROTECT, related_name='player2')
winner = models.ForeignKey(User, on_delete=models.PROTECT, related_name='winner', null=True, blank=True)
Now I want to get the standings for a specific heat. In other words, I want to get all unique players in that heat, together with how many wins they got (thus where they are in Game.winner), and how many losses they got (thus where Game.winner is not that player but it is not Null, and they are in either Game.player1 or Game.player2.)
Ideally, this should then even be ordered by wins (descending), losses (ascending).
I've been looking through the aggregation docs from Django, but I don't see how to start since I need to get so many different things all combined.

Related

Multiple related foreignkeys

class Flow(models.Model):
name = models.CharField(max_length=200)
pre_requisite = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
pre_requisite_status = models.ForeignKey("FlowStepStatus",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='pre_requisite_status')
This gives me one pre-requisite and it's status (pre_requisite_status). But I want to have flexibility for multiple pre_requisite and their respective statuses. How can I modify model to have it?
If I understood your requirements correctly - you want a Flow to have more than one pre_requisite and pre_requisite_status. In that case you need to introduce another model (in other words database table) that refers to the Flow model as a foreign key.
class Flow(models.Model):
name = models.CharField(max_length=200)
class PreRequisite(models.Model):
flow = models.ForeignKey(Flow, on_delete=models.CASCADE, related_name='pre_requisites')
pre_requisite = models.ForeignKey(Flow, null=True, on_delete=models.SET_NULL)
pre_requisite_status = models.ForeignKey("FlowStepStatus",
on_delete=models.SET_NULL,
null=True,
blank=True)

Django loop through a form multiple choice field

I am very new to django and I'm making a project that tracks medications in our drug safe. Part of our daily activities is to check the amount of each drug in the safe and document each amount. In my model for the safe, I have a field "drug_name" that is a foreign key to a list of medications. I want to make a model form that auto populates each choice in the field and asks for the amount of the drug in the safe. Something like:
Drug Name 1
Amount:_________
Drug Name 2
Amount:_________
and so on.
Here is my model
class Safe(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
date_created = models.DateTimeField(auto_now=True)
drug_name = models.ForeignKey('components.Drug', related_name='drug_remove', on_delete=models.PROTECT, default=0, limit_choices_to={'is_active': True})
amount_removed = models.IntegerField(blank=True, null=True)
amount_added = models.IntegerField(blank=True, null=True)
amount_in_safe = models.IntegerField(blank=True, null=True)
incident_number = models.CharField(max_length=20, default=0, blank=True)
patient_name = models.CharField(max_length=20, default=0, blank=True)
medic_unit = models.ForeignKey('components.MedicUnit', related_name='medic_unit', on_delete=models.PROTECT, blank=True, null=True)
free_text = models.CharField(max_length=1000, default=0, blank =True)
I'm not sure if I could submit all at once or if I would have to submit one drug at a time. Either way would work well as long as the user didn't have to manually select each medication. Thanks ahead of time for any help.

Django QuerySet, Filtering Data Based on The Latest Entry of Each Data's Column/Field equals to a particular Value

#models.py
class Orders(models.Model):
orderid = models.IntegerField(db_column='orderID', primary_key=True)
createdate = models.DateField(db_column='createDate', blank=True, null=True)
pickupdate = models.DateField(db_column='pickupDate', blank=True, null=True)
returndate = models.DateField(db_column='returnDate', blank=True, null=True)
pickupstore = models.ForeignKey(Branch, models.DO_NOTHING, db_column='pickupStore', blank=True, null=True,related_name = 'pickupstore')
returnstore = models.ForeignKey(Branch, models.DO_NOTHING, db_column='returnStore', blank=True, null=True,related_name = 'returnstore')
rentedvehicle = models.ForeignKey('Vehicles', models.DO_NOTHING, db_column='rentedVehicle', blank=True, null=True)
customer = models.ForeignKey(Customer, models.DO_NOTHING, db_column='customer', blank=True, null=True)
class Vehicles(models.Model):
vehicleid = models.IntegerField(db_column='vehicleID', primary_key=True)
make = models.CharField(max_length=45, blank=True, null=True)
model = models.CharField(max_length=45, blank=True, null=True)
series = models.CharField(max_length=45, blank=True, null=True)
Orders model have foreign key rentedvehicle which refers to Vehicles models
I have filtered the data based on the pickupstore state, e.g. The list of vehicles that are picked up from store in a particular state
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state'])
I want to be able to filter the filtered data above so that I can get a list of vehicles that are picked up from store in a particular state WITH its latest entry in Orders models has returnstore__state == a particular state
So basically, I want to achieve this:
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state']).filter(the latest entry returnstore state =request.POST['state'])
Many possible solutions. Optimal depends on your Django version (1.11 or higher?). Here's one possible solution:
from django.db.models import Max, F
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state']).annotate(max_date=Max('orders__returndate')).filter(orders__return_date=F('max_date')).filter(orders__state = request.POST['state'])
What's happening here is that we're identifying the most recent return date, then filtering the orders to only include the most recent, then filtering the Vehicles on the state of that latest order.

Problems with Django model relations

I've little problem with django models. I'm trying to create a game statistics service, but can't figure out how could I pick players from each team as a starting roster (doesn't contain all of the team players) of the game. Picking should work so that home and visitor has separated player lists. And then it should be possible to create eg Goal object where I could pick player as scorer only from the starting roster. I've already tried to put home and visitor players as ManyToManyField in the Game model, but it won't work. It needs some filtering at least.
class Game(models.Model):
series = models.ForeignKey(Series, related_name="game_series")
date = models.DateTimeField(default=None, blank=True, null=True)
home = models.ForeignKey(Team, related_name="game_home")
visitor = models.ForeignKey(Team, related_name="game_visitor")
class Goal(models.Model):
game = models.ForeignKey(Game, related_name="goal_game")
minutes = models.PositiveIntegerField(default=None, blank=True, null=True)
seconds = models.PositiveIntegerField(default=None, blank=True, null=True)
scorer = models.ForeignKey(Player, related_name="goal_scorer")
assist = models.ForeignKey(Player, related_name="goal_assist")
class Save(models.Model):
game = models.ForeignKey(Game, related_name="save_game")
player = models.ForeignKey(Player, related_name="save_player")
count = models.PositiveIntegerField(default=None, blank=True, null=True)
The question is: how should I modify models to achieve the desired result? Note: I'm using admin views for data input, so the proposed resolution should work from there.
EDIT: There is also Player model which I forgot to explain earlier. So, both of teams has already defined list of players where to pick roster for the game.
class Player(models.Model):
team = models.ForeignKey(Team, on_delete=models.PROTECT, related_name="player_team")
firstname = models.CharField(max_length=200, default=None, blank=True, null=True)
lastname = models.CharField(max_length=200, default=None, blank=True, null=True)
number = models.IntegerField(default=None, blank=True, null=True)
description = models.TextField(default=None, blank=True, null=True)

Extending a Django Database dynamically?

I am building an app in Django that allows users to add items to their profile, such as previous work experience. The problem that I am running into is that different users have different amounts of experience. My current approach is to have a model that looks something like:
class MyModel(models.Model):
owner = models.ForeignKey(User, related_name='modelowner', on_delete=models.CASCADE)
experience1_company = models.TextField(null=True, blank=True)
experience2_company = models.TextField(null=True, blank=True)
experience3_company = models.TextField(null=True, blank=True)
...
experience10_company = models.TextField(null=True, blank=True)
experience1_title = models.TextField(null=True, blank=True)
experience2_title = models.TextField(null=True, blank=True)
experience3_title = models.TextField(null=True, blank=True)
...
experience10_title = models.TextField(null=True, blank=True)
In my present model the user can enter up to 10 previous roles, which covers about 95%+ of users. However, this obviously has the problem where each previous experience a user enters has lots five other attributes (start date, end date, title, description, location). meaning that the model ends up with something like 60 total attributes... and if I need to add something new, I have to add it 10 times.
Question: Is there a way to dynamically build new model attributes for the users that have more than X number of experiences or is best practice to have each one explicitly defined in the model and just have a practical cutoff (e.g., you can only enter up to 10)?
You would have to change your model to represent one experience like this:
class Experience(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
company = models.TextField(null=True, blank=True)
title = models.TextField(null=True, blank=True)
# and as much other fields as you like:
start_date = models.DateField()
end_date = models.DateField()
description = models.TextField(null=True, blank=True)
location = models.TextField(null=True, blank=True)
Now you can create unlimited Experience instances for each user, and fetch them with:
user = User.objects.get(username='bob')
Experience.objects.filter(owner=user)
or
user.experience_set.all()
Documentation on this topic is in Making queries - following relationships "backward"
You need a model to store work experience information such as(job_title,company_name, start_date, end_date, duties) and link this work experience model to the user profile. something like below:
class WorkExperience(models.Model):
person = models.ForeignKey(User, blank=True, null=True)
job_title = models.CharField(max_length=125)
company_name = models.CharField(max_length=125)
start_date = models.DateField()
end_date = models.DateField()
duties_description = models.CharField(max_length=125)
This way, your application can accommodate any number of WorkExperience per user