I'm trying to figure out how to execute the following sql join statement in Django without resorting to just raw sql. Is there a way to do it?
Select * from playertable, seasontable where player.id = season.player_id
Here are my models. Just to clarify, I used abbreviated table names in the above query for clarify
class Player(models.Model):
name = models.CharField(max_length=200)
team = models.CharField(max_length=3)
position = models.CharField(max_length=3)
class PlayerSeason(models.Model):
player = models.ForeignKey(Player)
year = models.IntegerField()
games_played = models.IntegerField()
goals = models.IntegerField()
assists = models.IntegerField()
points = models.IntegerField()
plusminus = models.CharField(max_length=200)
pim = models.IntegerField()
ppg = models.IntegerField()
shg = models.IntegerField()
gwg = models.IntegerField()
otg = models.IntegerField()
shots = models.IntegerField()
shooting_percentage = models.DecimalField(max_digits=5, decimal_places=2)
toi = models.CharField(max_length=200)
sftg = models.DecimalField(max_digits=5, decimal_places=2)
face_off = models.DecimalField(max_digits=5, decimal_places=2)
How should I do this with a Django QuerySet?
If all you wanted to do was to get all the players associated with a given season you could make use of Django's backwards relationships
When you use a ForeignKeyField to a model, in this case Season, the that model instances get an attribute which allows you to get a queryset of all the related objects.
In your example you could use season.player_set.all().
You can pass an optional parameter related_name to the ForeignKeyField that allows you to change the name of the season attribute.
Is there a way to do it?
No. Django's ORM deals with one model at a time, and you are getting columns from two tables. Perform a query on either of the models and then access the appropriate field to get the related model.
Related
I am attempting to merge and pull data from three Django models into a view. Players and Events relate to each other in the Details model (a player can attend many events) using models.ForeignKey.
In other platforms I would have written a DB View to join tables and the application would query that view.
From what I understand Django does not support data views within Models.
Looking for help on how I would approach this in Django.
class Players(models.Model):
firstName = models.CharField(max_length=255)
lastName = models.CharField(max_length=255)
highSchool = models.CharField(max_length=255)
gradYear = models.IntegerField()
slug = models.SlugField(default="", null=False)
class Events(models.Model):
title = models.CharField(max_length=255)
location = models.CharField(max_length=255)
date = models.DateField()
class Details(models.Model):
event = models.ForeignKey(Events, on_delete=models.CASCADE)
player = models.ForeignKey(Players, on_delete=models.CASCADE)
height = models.IntegerField(default=None, blank=True)
weight = models.IntegerField(default=None, blank=True)
def playerdetail(request,slug):
playerinfo = Details.objects.get(id=1)
template = loader.get_template('playerdetail.html')
context = {
'playerinfo': playerinfo,
}
return HttpResponse(template.render(context, request))
You are actually doing what you needed to do with the code you provided.
When you are invoking a query on a model that connects those two entities (Players,Events), it performs the join when you try to access each of these properties through the foreign key fields.
For example, for accessing the player information (which makes the Django ORM perform the join operation in the background):
# Get the first name of the player
first_name = playerinfo.player.firstName
For filtering and showing in other places, you can use the notation field__subfield
For more information, please read the examples of this website:
https://books.agiliq.com/projects/django-orm-cookbook/en/latest/index.html
I have a model Allotment
class Kit(models.Model):
kit_types = (('FLC', 'FLC'), ('FSC', 'FSC'), ('Crate', 'Crate'), ('PP Box', 'PP Box'))
kit_name = models.CharField(max_length=500, default=0)
kit_type = models.CharField(max_length=50, default=0, choices=kit_types, blank=True, null=True)
class AllotmentFlow(models.Model):
flow = models.ForeignKey(Flow, on_delete=models.CASCADE)
kit = models.ForeignKey(Kit, on_delete=models.CASCADE)
asked_quantity = models.IntegerField(default=0)
alloted_quantity = models.IntegerField(default=0)
class Allotment(models.Model):
transaction_no = models.IntegerField(default=0)
dispatch_date = models.DateTimeField(default=datetime.now)
send_from_warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
flows = models.ManyToManyField(AllotmentFlow)
For a stacked graph I am trying to get the data of different kit_type alloted in different months.
For that I have tried annotate but it isn't getting the desired results
dataset = Allotment.objects.all().annotate(
month=TruncMonth('dispatch_date')).values(
'month').annotate(dcount=Count('flows__kit__kit_type')).values('month', 'dcount')
Expected Output:
[{'month':xyz, 'kit_type':foo, count:123},...]
I am getting the month and count of kit type from above but how do I segregate it by kit_type?
having a field that represents your choice field names in this query is difficult
instead how about use the Count filter argument and annotate to get what you want
dataset = Allotment.objects.all().annotate(month=TruncMonth('dispatch_date')).values('month').annotate(
FLC_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="FLC")),
FSC_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="FSC")),
Crate_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="Crate")),
PP_Box_count=Count('flows__kit__kit_type', filter=Q(flows__kit__kit_type="PP_Box")),
).values('month', 'FLC_count', 'FSC_count', 'Crate_count', 'PP_Box_count')
I have two models with ManyToManyField relationship:
class Education(models.Model):
title = models.CharField(default=None, max_length=100)
content = models.TextField(default=None)
price = models.ManyToManyField(Price)
class Price(models.Model):
cost = models.CharField(default=None, max_length=20)
created_at = models.DateTimeField(auto_now=True, null=True, blank=True)
I can fetch all rows like this:
result = Education.objects.filter(price__in=Price.objects.all()).select_related('Price')/
.values_list('title', 'content', 'price__cost', 'price__created_at')
But now i want to group by education.id and the cost parameter should be latest parameter that inserted(based on created_at).
So i want to have list of all Education with latest cost that inserted for every education.
Will it work for you, It will return the respective id
Education.objects.filter(price__in=Price.objects.all()).select_related('Price').values('id').annotate(price_id=Max('price__id'))
I have four models, three of which have ‘independent’ fields but the fourth models has ForeignKey links to the other three.
class PreCheck(models.Model):
name = models.CharField(max_length=120)
time_in = models.DateTimeField(auto_now_add=True)
is_insured = models.BooleanField()
class MainCheck(models.Model):
height = models.FloatField()
weight = models.IntegerField()
class PostCheck(models.Model):
sickness = models.CharField(max_length=30)
medication = models.CharField(max_length=30)
class MedicalRecord(models.Model):
patient = models.ForeignKey(User)
next_check_date = models.DateTimeField()
payment_amount = models.IntegerField()
initial_check = models.ForeignKey(PreCheck)
main_check = models.ForeignKey(MainCheck)
post_check = models.ForeignKey(PostCheck)
Assume a patient goes in a room, a precheck is done and saved, then other checks are done and finally a final record is set.
Ideally, I would like to fill in forms for the different models at different times possibly in different pages/tabs.
The admin has popups for the MedicalRecord model but in the frontend its hard to write javascript for that.
Another option would be to fill in the modelforms separately and do a str return function then select that from dropdowns in the MedicalRecord form( which I’m trying to avoid)
Just add blank=True, null=True for each ForeignKey fields.
initial_check = models.ForeignKey(PreCheck, blank=True, null=True)
main_check = models.ForeignKey(MainCheck, blank=True, null=True)
post_check = models.ForeignKey(PostCheck, blank=True, null=True)
at the initial check, you can create MedicalRecord with help of MedicalRecord model-form, this time main_check and post_check record can be left blank.
after main check, you can update MedicalRecord with main_check details, this time left blank post_check record, and keep updating your MedicalRecord on different pages/tabs with available details.
I have a product model with the following:
class Product(models.Model):
name = models.CharField(max_length=255)
handle = models.CharField(max_length=55)
summary = models.CharField(max_length=255, blank=True)
category = models.ForeignKey(Category)
Above is just the product detail, but there are 3 types of pricing:
Standard - normal regular pricing by filling the price field
Variant - pricing with product variants (size, colour, etc.) with their respective prices
Combined - this is a combination of other saved products, with a custom price provided by user.
For 1 and 2 I have the below model. If the product model has more than 1 price on StandardProduct model then I know it has variants.
class StandardProduct(models.Model):
variant_type = models.CharField(max_length=55)
variant_name = models.CharField(max_lenght=55)
product = models.ForeignKey(Product)
sku = models.CharField(max_length=55, blank=True, null=True)
barcode = models.CharField(max_length=55, blank=True, null=True)
selling_price = models.DecimalField(max_length=15, decimal_places=2)
How do I go about creating the CombinedProduct model? The combined product model can have different created products inside (with their quantities). The price is specified by the user. Below is what I have, but I don't know how to approach this.
class CombinedProduct(models.Model):
product = models.ForeignKey(Product)
item = models.ForeignKey(StandardProduct)
quantity = models.DecimalField(max_length=15, decimal_places=2)
How do I go about creating the CombinedProduct model? The combined
product model can have different created products inside (with their
quantities). The price is specified by the user. Below is what I have,
but I don't know how to approach this.
What you probably want is a ManyToManyField with through option.
This is just a very rough sketch up - I don't get your Product/StandardProduct and the relations.
class CombinedProduct(models.Model):
products = models.ManyToManyField(
Product,
through='Combination'
)
class Combination(models.Model):
product = models.ForeignKey(Product)
combined_product = models.ForeignKey(CombinedProduct)
price = models.DecimalField(max_length=15, decimal_places=2)
quantity = models.DecimalField(max_length=15, decimal_places=2)