one-to-many relationships with django - django

I intend to create a teaming system, where each team may contain multiple contestants. The contestants is actually auth.User. Something similar to:
Team:
Contestant1
Contestant2
.
.
ContestantN
Since a contestant is actually a user which I cannot modify to have a foreignkey to team. What is the best way to achieve this?
The ways I though was:
Create a OneToOne profile for user which points to a team.
Define a ManyToMany relationship between user and team where user has to be unique.
A Pause
I am redesigning the structure of my application, so I will rephrase the question again
Thanks for your replies, I will consider them and see if one of them fits.

You can do this:
class Team(models.Model):
contestants = models.ManyToManyField(User, through='Contestant')
class Contestant(models.Model):
team = models.ForeignKey(Team)
user = models.ForeignKey(User)
[here go Contestant data fields]
This allows one user to take part in different teams, but if you don't want to allow this, you can add unique=True to Contestant.user.

The best way would be to extend the functionality of default accounts and create a new user model. The new user model can then have a foreign key to team. Like this.
class UserExtended(models.Model):
def __unicode__(self):
return self.user.username
user = models.OneToOneField(User, unique=True)
team = models.ForeignKey(Team)
User.profile = property(lambda u: UserExtended.objects.get_or_create(user=u)[0])
Now you can use the "UserExtended" in place of normal User.

I would create a contestants field on the Team model like so:
from django.contrib.auth.models import User
contestants = models.ManyToManyField(User)
You can't specify unique=True on a ManyToManyField. The good news is that it won't add the same contestant to the same team twice so you won't need to check if the contestant is unique.

I would say your best bet is to create a Contestant model. You'll probably end up needing to store more information about a contestant that is team-specific but separate from a player (such as whether the contestant is a starter, the contestant's number, and so on). Creating a Contestant model allows you to store that information separate from the User, and you would have a ForeignKey in the Contestant model referencing Users, and another ForeignKey in the Contestant model referencing Teams.

Related

Modeling favorites in Django from two different models

I have a Netflix clone app that I am creating and I am having difficulty with the models.
I have a Movie model that has fields for the movie such as a title, duration, rating, etc.
I am not sure how I should model my database but what I believe I should be doing is a ManyToMany relationship, such as, a user can favorite many movies and a movie can be favorited by many users.
However, if I do it like this I feel that I would end up with a Favorites table that would have many users and movies and possible see this as an issue having to go through each row to find the current user rather than doing maybe a OneToMany relationship, such as, a user can favorite many movies and a movie can be favorited by a user.
So first, I am not sure what the proper way of modeling this would be.
I also do not know how to add this relationship to my user model because I am using the User model that I brought in from django.contrib.auth.models
I am having a lot of trouble trying to think of a solution for this and I don't want to just add a many to many field for users to the movie table that I have without understanding if and why it is a good/bad approach.
How about something like:
class User(...):
first_name = models.CharField(...)
....
class Movie(models.Model):
title = models.CharField(...)
...
class Favorite(models.Model):
user = models.ForeignKey('User', related_name='favorites', ...)
movie = models.ForeignKey('Movie', related_name='favorites', ...)
Then we can do:
# a particular user's favorite movies:
user = User.objects.get(id='the_user_id')
user.favorites.values('movie')
# number of users who have favorited a particular movie:
movie = Movie.objects.get(id='the_movie_id')
movie.favorites.count()

How to best create connections for a booking app?

I am new to Django and relational databases coming from the Firebase world. I am having trouble figuring out the best modeling for a Doctor-Patient booking app and generally how relational DBS works best; I would like to minimize future problems by doing a great job now. I am going to use Django and Django Rest Framework at the backend to feed a React frontend.
So far, I've created these models in a clinic app. Patients and Secretaries are going to be part of the users, and so are Doctors. I then create the Serializers and Viewsets for the API.
class Clinic(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
accepted = models.BooleanField(default=False)
class Doctor(models.Model):
clinic = models.ManyToManyField(
Clinic, related_name="doctor")
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.EmailField(max_length=240, default="email")
appointment_duration = models.IntegerField(default=20)
class Secretary(models.Model):
clinic = models.ForeignKey(
Clinic, on_delete=models.CASCADE, related_name="secretary")
name = models.CharField(max_length=200)
email = models.EmailField(max_length=240, default="email")
doctors_responsible_for = models.ManyToManyField(Doctor)
class Patient(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.EmailField(max_length=240, default="email")
date_of_birth = models.DateField()
age = models.PositiveIntegerField(default=0)
Should I create a User model to be able to differentiate users (Doctors, Secretaries and Patients)? They are all going to be able to register and log in and each will see different things on the page. Should I just return 'is_doctor' or 'is_secretary' from the serializer API and show different content from there?
I'm confused as to how I would connect a User model with a Doctor or Secretary model, for example, or if I even need to since they're all users...
How would I differentiate users (Doctor, Secretary, Patient) at the registration moment? E.g., for each of them to have a different registration form with a boolean for is_doctor, is_secretary?
I can't to come up with a solution for storing booked appointments. I'm wondering if I should create a new model, Bookings, for saving bookings but I'm not sure if this booking model should hold every single booking (from any patient to any doctor), considering this app will be used by a lot of people. Or should bookings be under each patient and each doctor?
In this case, secretaries will also be able to manually add bookings to a Doctor calendar and add the patient as well.
I am building all of this in a single app, clinic, perhaps it is recommended to create different apps for this?
Each doctor will need to have its own calendar for this app to work, with say, 'day 12, blocks of 20mins from 09:00 to 11:30'. Should I create a Calendar model? Or how is it best to achieve this? How to best come up with this model? This calendar will be populated with blocks of time from whatever each doctor chooses as their availability.
First of all, I'm a django noob, so please read the following with that it mind.
Looks pretty good - the only thing I see missing is how you link patients to clinics and or doctors.
The other thing I notice is how doctors can have multiple clinics. I assume each clinic has its own calender, rather the doctor itself? Or maybe both? i.e. Even if a doctor was available on his calendar, he might not have a room at the clinic for the patient as other doctors' calenders would clash with it.
Personally, I wouldn't create a new app for clinic unless you want to model it in far more detail. Keep it simple initially.
Also, if you're allowing doctors, secretaries, and patients to login to your site, it might be better to have consumer/provider class model descending from custom user. ideas...
I would start thinking about the problem in more abstract terms. Service/provider/consumer.
But, I think you're on the right track.
I can throw in some ideas.
Models
I think you are on the right track. You just need to associate models Doctor, Secretary and Patient to the User model. I would recommend you to create a custom user model inherited from AbstractUser.
In this model, you can either add a choice field with choices for each type of user. link to docs
Also, you need to link the user model with the correct model.
One way to do is to have a OneToOneField for the user model in all your user type models: Doctor, Secretary, Patient
Or you can explore generic relations. It will further streamline things for you. link to docs.
Signup
You can provide a field for users to select at the time of signup, or provide separate links to signup and handle things at the backend. Something like If you are a doctor, click here to signup. In both cases, you'll need to override the signup process.
So a signup link can look like: /signup/doctor/ or /signup/patient/. All signup will be using the same view, just different url kwargs. link to docs
You can just create rows on the relevant model for user type on form success.
Booking
Yes, you need to create a separate model, and you can store all your bookings in this model. Doesn't matter how many users use your app. Just use a good database solution, like Postgres. There are ways to optimize your queries, like indexing, don't worry about it for now. Just make sure to save all references like, patient, doctor, created, last modified, created by which user, from_datetime, to_datetime, etc.
It would be better to handle the 20 min appointment blocks in forms.py.
You can create a list of acceptable time blocks, so that if in future you want to change this time to say 30 min, its easily doable. Just handle all validations at the form level and it should do the trick.

Add a unique "intermediary" model to all my Django ManyToManyField()

Hello Awesome People!
Such a question that I have made a lot of searches for it. I am done building a website two(2) months ago, but today The team decides to track every time an instance has been added to a Model in ManyToManyField() fields.
I was thinking using the through argument to point to the model that will act as an intermediary may work but not at all in my case (70%). Just Because I want to have a unique intermediary model that will record for all ManyToManyField()
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateTimeField(auto_now_add=True)
Ah! Something is required. I need to explicitly specify foreign keys to the models that are involved in the many-to-many relationship.
Django ContentType may anticipate for all my models, but it's not working, I wonder why? it also contains ForeignKey (the one required by an intermediary model).
Do I really need to edit all my ManyToManyField fields and create Model as much as ManytoManyField? is there a way to record date_joined without creating an intermediary model for each?
Are you perhaps looking for something like django admin's LogEntry model?
LogEntry contains the ContentType of the model instance that has changed, the id of the instance, the type of change and an abstract change message. With all of that you can retrace changes made to instances.
In django admin, the views take care of adding records to LogEntry via three methods log_change/addition/deletion: click.

django: creating two models depends on each other

trying to solve quite simple problem, but I'm a little lost.
class Person(models.Model):
created_by = models.ForeignKey(User)
class User(models.Model):
person = models.ForeignKey(Person)
User is user who use system, log in, create persons, etc.
Each Person has info who create it.
Each User should be just one Person also, but able to create unlimited Persons
So the question how to properly create User (on registration) and assign Person?
I can't save Person without user, also can't save User without Person.
I think use person.models.ForeignKey(Person, null=True) in User model is not good design, because User has to have Person.
Any suggestion?
Thank you
It looks like User should just inherit from the Person model, since every User is a Person. Incidentally this would also resolve your problem - creating User would create an associated Person automatically.
You should probably read about multi-table inheritance to fully understand how this would work.
Furthermore, the created_by field should have null=True specified, since the first Person wouldn't be created by anyone, so the first object need to have the Null value there.
class Person(models.Model):
created_by = models.ForeignKey('User', null=True)
class User(Person):
person = models.ForeignKey('Person')
Also, since you want the User model to by used as the AUTH_USER_MODEL you should read about requirements for such models.

In what model should I add the ManyToManyField?

I read the documentation about many-to-many relationships and the examples. What I could not find is a hint on where to put the ManyToManyField. In my case I have an extended user model Client and a model Pizza. Every client may mark one or more pizzas as favourites. Those are my two models:
from django.db import models
from django.contrib.auth.models import User
class Client(models.Model):
user = models.OneToOneField(User)
#? favourite_pizza = models.ManyToManyField()
class Pizza(models.Model):
name = models.CharField(max_length=255)
#? favourite_pizza = models.ManyToManyField()
In what model should I add the ManyToManyField? Does it matter?
PS The important information is how many favourite pizzas a client has (and which). It is less important how many clients marked a pizza as a favourite (and who). Consequently I would chose to put the ManyToManyField in the Client class.
From the Django documentation:
Generally, ManyToManyField instances should go in the object that’s going to be edited on a form.
Technically it does not matter. The question is from which model-side you will query the database.