relationships in django which one to use - django

I am having trouble trying to decide what kind of relationship I should use for my application.
I want to have a database that shows something like...
A Movie table with fields title, year, language, description, duration and so on.
A User table with fields username, email
(I am new to django and am not worrying about authentications or passwords or any of that for now)
I want a user to be able to favorite a movie so I am trying to wrap my head around how it would actually work, for instance, would it be a user can favorite many movies and a movie can be favorited by many users (this makes sense to me) or is it a user can favorite many movies and a movie is favorited by a user.
so If I pick the second option I guess it would be a one-to-many rather than the first option which is a many-to-many relationship. However, I am not sure which one is actually correct.
After looking at the docs in django for many-to-one I see that a foreign key should be given to the Movie that references a user from User but they use an option that has on_delete=models.CASCADE and to my understanding it seems like the movie will be deleted if i were to delete the user which of course I don't want.
I was hoping for a detailed explanation as to which relationship it oughta be and if it is a many-to-one relationship then what kind of option should i use for instance the on_delete=models.CASCADE is probably not what I should use to my understanding

Related

I'm using django to build a website and I want to link tutors and students

I'm currently stuck with the best way of assigning tutors to students and then tutors can add lessons for these students and they can both see these lessons, but you can only assign one foreign key to the class "MyLessons". So I'm not sure whether it's worth creating a MyStudents class, storing students inside this (but their user is the same as tutors except is_tutor=false) and then for each student creating a MyLessons class that the tutor can add to.
I think I can make an approach I'm just worried it won't be very efficient or there will be some serious problems later on. Such as the other way was that each lesson would auto take in the tutors email (I set the username to email) and then when displaying the tutors lessons it would go through every lesson and display the lessons with a matching email... problems are though, if I reassign a student to a new tutor I'd like the new tutor to see the lessons but this would mean manually changing each and if there are too many lessons and students the process would get slow.
A Tutor has many students. A student potentially has more than one tutor. So at first glance that's a ManyToMany relational field.
One thing that's at first confusing is that the relationship is symmetric, but is defined on one object and only implicitly on the other. But the implicit and explicit fields both work the same, for manipulating a set of relationships.
class Tutor( models.Model)
students = ManyToManyField( Student, related_name='tutors', ...)
then
student_instance.tutors.add( tutor_instance)
tutor_instance.students.add( student_instance)
both accomplish the same. (In the simplest case. Read the doc for the exceptions).
It may or may not help to know that behind the scenes, Django is manipulating an implicit table whose objects have two fields, a ForeignKey to a student and a ForeignKey to a tutor. It can sometimes be useful to make this table explicit, so you can attach extra information to the relationship such as date created, who created it, etc. Look up the "through" option of ManyToMany if you want to do this.
Further examples here.

Django Models: Creating Subtypes

I am new to Django and am working through some models on a project right now.
Is there a decent way to set the following up?
Using a model that ties to the auth_user model (UserAccount), I prompt users to select the type of account they have (Ex: Vendor or Buyer).
This part works fine... but I want to build the site experience based off of their account type. How would I create VendorProfile or BuyerProfile models (with differing data) based upon that option?
I might be over analyzing this, but basically I do not want any profiles to be linked to both types of data. Is that something I should just control with views, or is there a good way to lock my models and prevent duplicate information? Let me know if you think this is too broad, but I'm still on the conceptual level.
So:
auth_user model
UserAccount model:
user: one to one (User)
account_type: 'V' or 'B'
VendorProfile(?)
user: one to one (UserAccount where type='v')?
company name:
vendor code:
BuyerProfile(?)
user: one to one (UserAccount where type='b')?
favorite color:
pet's name:
yes you can do that. for that you need to change a small thing in the auth table of django and that is you need to add a column account_type where the V or B will be stored. Hope you can find it how to do it.
next is create 2 models for vendor and buyer. make a onetoonefield with the user table for storing the id of the user, in this models keep the extra information of the vendor or buyer you want to store.
hope it helps

Conditional Attributes for Django User based on Groups

A given user can be in zero or more of the following categories:
floor staff
managers
owners
If the user is floor staff they require extra attributes (e.g. seniority and staffType).
My initial attempt looked something like this:
Create a Group for each category (this seems to make sense since each type of user should have different permissions within the site)
Create a FloorStaff model with the required extra attributes and a 1-to-1 relationship with User
Handle User creation and FloorStaff creation separately (i.e. using separate forms, accessed separately). The form to create FloorStaff adds the User to the floor staff group automatically.
While this works, it is not the most intuitive way to add a new floor staff employee to the site. From a manager's perspective, filling out 2 forms to add one employee makes little sense. That is, if I hire someone new, I should be able to fill out a "new employee" form that includes adding said employee to the correct categor(y/ies) at the same time as adding their basic info, and, if that employee is to be floor staff then the extra attributes should be added as well.
I've been toying with creating a custom user model that includes the extra attributes, but this feels wrong given that not all Users are FloorStaff.
At this point all I can think to do is to build a custom view and HTML form, but that too seems to go against the Django way of thinking.
What is the most "Djangoific" way to do this?
I would recommend making seniority and staffType as optional fields, and then create a custom model admin that enforces providing those fields when floor staff is true

Multiplechoice widget with really big lsit

In my model Person can have more than one partner, so the ManyToMany Model is the only answer (this has to be ManyToMany for other reasons, so please don't think about changing it).
If I use default widget i got a list of all persons with selected one, two maybe three persons (which are partners of Person).
It would be ok, if the Person list is about 10-100 - and it works on test database. But my prod database has 10.000 persons or more, so the ModelMultipleChoice widget would be filled with 10.000 records, and finding the correct partner will last ages, and memory usage isn't trivial.
I need only to see names of partners with possibility to unset it from person, and some possibility to add new just typing name. The best solution is to show listbox with filtered names after typing three or four first letters, but any solution would be great.
With forms it would be easier, but I need it in admin, so I'd like to use django admin standards.

Django Model Table temporary data vs. permanent data

I am writing a trip planner, and I have users. For the purposes of this question, lets assume my models are as simple as having a "Trip" model and having a "UserProfile" model.
There is a functionality of the site that allows to search for routes (via external APIs), and then dynamically assembles those into "trips", which we then display. A new search deletes all the old "trips" and figures out new ones.
My problem is this: I want to save some of these trips to the user profile. If the user selects a trip, I want it to be permanently associated with that profile. Currently I have a ManyToMany field for Trips in my UserProfile, but when the trips are "cleaned/flushed", all trips are deleted, and that association is useless. I need a user to be able to go back a month later and see that trip.
I'm looking for an easy way to duplicate that trip data, or make it static once I add it to a profile . .. I don't quite know where to start. Currently, the way it is configured is there is a trips_profile datatable that has a foreign key to the "trips" table . . . which would be fine if we weren't deleting/flushing the trips table all the time.
Help appreciated.
It's hard to say exactly without your models, but given the following layout:
class UserProfile(models.Model):
trips = models.ManyToManyField(Trip)
You can clear out useless Trips by doing:
Trip.objects.filter(userprofile__isnull=True).delete()
Which will only delete Trips not assigned to a UserProfile.
However, given the following layout:
class Trip(models.Model):
users = models.ManyToManyField(User)
You could kill the useless trips with:
Trip.objects.filter(users__isnull=True).delete()
The second method has the side benefit of not requiring any changes to UserProfile or even a UserProfile at all, since you can then just get a Users trips with:
some_user.trip_set.all()