Merge Django models into a view - django

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

Related

Django ORM Query Optimization Issue

I am making a blog website and I am facing some issues with the Query performance.
I have 3 models
User Model -> Users (To store user email, Password etc)
Post Model -> Actual Posts
people Model -> (To store users extra information)
Post Model ->
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
title = models.CharField(max_length=255,null=True)
description = models.CharField(max_length=1000,null=True)
Likes = models.ManyToManyField(to=User, related_name='Post_likes')
favourites = models.ManyToManyField(to=User,blank=True,related_name="favourite")
People Model ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Now as both of these models are connected to User model. I want to query the Post model and get the user photo in the template. Now when I use post.user.people.photo then for every post it generates a seperate query to DB resulting in slowness. I would like to use Join here to combines multiple tables and fetch all the records at once.
I am currently using following Query ->
posts = Post.objects.select_related().prefetch_related('images_set').annotate(comments_Count = Count('comments_post',distinct=True)).annotate(Count('Likes',distinct=True)).all().order_by('-id')
You can perform a .select_related(…) [Django-doc] on the user and the people with user__people, so:
posts = Post.objects.select_related(
'user__people', 'category'
).prefetch_related('images_set').annotate(
comments_Count = Count('comments_post',distinct=True),
Count('Likes',distinct=True)
).order_by('-id')
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django Forms multiple foreignkey

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.

How to Left Join using Djangos ORM

I have to following models:
class Playlist(models.Model):
audio_files = models.ManyToManyField(AudioFile, related_name='in_playlists',
class AudioFile(models.Model):
listeners = models.ManyToManyField(User, related_name='listened_to', through='Progress', blank=True)
class Progress(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE)
lesson = models.ForeignKey(AudioFile, on_delete=models.CASCADE)
progress = models.FloatField(default=0)
Now I want a Django Query which lists all AudioFiles in a playlist but also attaches the progress in them for a specific user. In SQL this would be a LEFT JOIN. But I'm sure this is possible with django ORM as well.
I have tried:
playlistXYZ.audio_files.all().annotate(progress_num=models.Case(models.When(listeners__pk=1, then=models.F('listeners__progress__progress')), default=models.Value(0), output_field=models.FloatField()))
But it doesn't do what i want.

Is it possible to have a class as your model field in Django?

I am currently trying to create a health network website in Django.
The idea is that there will be a class called User inside my registration application. One of the states stored inside User is which hospital the user is registered into.
I created another Hospital within the registration app. I want to user that model Hospital as one of the model field for the hospital_used state. How do I do that? Below is a portion of my UML that illustrates the relationship
UML Diagram
Below is a portion of my UML that illustrates the relationship
png
Here is the code I have for it so far. The code where it is encapsulated with an asterisk is what I need help with.
class Hospital(models.Model):
hospital_Name = models.CharField(max_length=150)
def __str__(self):
return "Hospital Name: " + str(self.hospital_Name)
class User(models.Model):
PATIENT = 'Pat'
DOCTOR = 'Doc'
NURSE = 'Nurse'
ADMINISTRATOR = 'Admin'
user_type_choice = {
(PATIENT, 'Patient'),
(DOCTOR, 'Doctor'),
(NURSE, 'Nurse'),
(ADMINISTRATOR, 'Administrator'),
}
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
*preferred_hospital = Hospital(models.CharField(max_length=50))*
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
Thank you StackOverflow Buddies
I would advise you to read this material on tutorials on how to create simple models.
What you want here is to use the ForeignKey method.
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
preferred_hospital = models.ForeignKey(Hospital, on_delete = models.CASCADE)
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
You do not have to use on_delete = models.CASCADE but it is best that you handle what should happen when you delete an Hospital.
Know that you can also have OneToOne, ManyToOne, or ManyToMany fields, that are all described here.

Django one form / two models

I have a very simple model for tracking events:
class Event(models.Model):
description = models.TextField()
location = models.ForeignKey(Location)
start = models.TimeField()
duration = models.IntegerField()
event_date = models.DateField()
creator = models.ForeignKey(User)
and I opted to extract the location in a separate table in order to be able to perform queries:
class Location(models.Model):
city = models.CharField(max_length=20)
address = models.CharField(max_length=30).
What would be the best way to create a form for inserting/updating events, taking into account that the location should be done separately and than linked via ID in the event instance? I wanted to da maybe some autocomplete field for the location address and city, but to keep it on the same form for simplicity?
Define your own widget for the ModelChoiceField in the ModelForm that is generated for the ForeignKey.