How Do I Represent Student-Lecturer Relationship in Django? - python

So I'm trying to make a web app that is meant to aid interaction between students and teachers.
However, I need to know how to structure the model of relationships in Django. Here are 2 things you should know:
A teacher can have many students (users) under him or her.
A student can only have one user as his teacher.
In other words, teachers are meant to have as many students as possible, while each student can only have one teacher.
How should I represent this in Django? And what's the best way to manage this relationship? For the latter question, I'm thinking about creating a class that looks like this:
class Relationship(models.Model):
##student and lecturer models shall inherit the User class; hence, the
student = models.ForeignKey(User, related_name = 'lecturer_set')
lecturer = models.ForeignKey(User, related_name = 'student_set')
class Meta:
unique_together = ('student', 'lecturer')
PS: I know the above class might be wrong. Just trying to explain what I need to implement in the Relationship class.

This is a standard one-to-many relationship, which is represented in Django by a simple ForeignKey.
class Student(models.Model):
teacher = models.ForeignKey(Teacher)
You don't need the Relationship model at all.

Related

Is there a way to build dynamic models in Django?

I am currently building a project in Django, and I was wondering if is there a way to build a dynamic model. I want to create a model with a group of user, and the table structure is the following:
Group Name
User 1
User 2
User 3
User ...
But I want to make users dynamic, I mean, if the group has only 2 users the model will only put 2 users fields in the model, and if the group has 10 user the model put 10 users fields in the model.
Does someone know a way to do this? Is it even possible?
I hope I made it clear enough for you guys!
If you have any questions please post in the comments and I will answer as fast as I can.
Sorry for the english tho! Not my main language.
Think this way.
One group may have many users and one user can be in may groups you can use ManyToManyField.
So you need something like:
# default user model or custom user model
class User():
...
def __str__(self):
return self.username
class Group(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True, null=True)
users = models.ManyToManyField(User)
class Meta:
ordering = ['-id']
def __str__(self):
return self.title
this is not possible in django. because the models should be clear to make tables in database. but you can handle this with many-to-many relationship. as the django documents say link

How to inject a many-to-many relationship into third-party models?

I want to insert a many-to-many relationship into some models, without having to completely rewrite the models.
For example, consider the django User model and a model Foo from a third-party module I've installed.
If I 'owned' Foo I could just do:
class Foo(models.Model):
users = models.ManyToMany(User)
Then, if I wanted to add a Foo to user, or vice versa I could do:
my_user.foo_set.add(my_foo)
my_foo.users.add(my_user)
But I don't 'own' either code, and I want to inject this relationship, so I can do the above.
Now, if I wanted I could even do a through relationship through a model I made and and put that on either side, but that still requires altering the models.
Now, behind the scenes it looks like django many-to-many relationships are models (they definitely have tables), is it possible to make this code:
class FooUserRelationship(models.Model):
foo = ForeignKey(Foo)
user = ForeignKey(User)
Act just like a many-to-many relationship?
you can use proxy models. Here person is a 3rd party model and Myperson is a your model modifying extra attributes to the main models. for more details https://docs.djangoproject.com/en/1.9/topics/db/models/#proxy-models
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class MyPerson(Person):
users = models.ManyToMany(User)
class Meta:
proxy = True
The cleanest way i can think of is to provide a middle class (or you could subclass which would provide the almost the same queries) with a onetoone to one side and then many to many
class FooUser(models.Model):
user = OneToOneField(AUTH_USER_MODEL)
foo = ManyToMany(Foo)
my_user.foouser.foo_set.add(my_foo)
my_foo.foousers.add(my_user.foouser)
Now I admit that this isn't the cleanest way of doing things since it would involve a further SQL join when retrieving results, but it does keep in tact your link and provides a way to modify as you please.

through model for an Abstract model

I have an Abstract model:
class Distributor(models.Model):
class Meta:
abstract = True
and 2 models which inherit it:
class DistributorGroup(Distributor):
pass
class DistributorPerson(Distributor):
pass
also I have a llink model:
class Link(models.Model):
distributors_persons = models.ManyToManyField(
'people.DistributorPerson', blank=True, related_name='distributors_persons_of_links')
distributors_groups = models.ManyToManyField(
'groups.DistributorGroup', blank=True, related_name='distributors_groups_of_links')
A link can have a relation with one of the distributors. I accomplished this behavior by adding 2 m2m and setting blank=True to both.
Now I realized that I need a through model to connect Distributors and Link. But as through model can't have an abstract model as a foreign key I don't know what to do. Do I need to create 2 separate through models for DistributorPerson and DistributorGroup or there is a way to accomplish this with 1 through model. Also I don't know if my 2 m2m in Link model are a proper way to accomplish the behavior that I want.
So I would like to know what is the way to organize these m2m models with an abstract model.
The first question is whether DistributorPerson and DistributorGroup really need to be separate tables. If they're very similar it might make sense to just use a single table. (For example, if you were modeling phone numbers you probably wouldn't use separate Home, Work, and Mobile tables, you'd instead use a single table with a type field.)
(And note that you can use proxy models to allow different Django models to share the same database table.)
If you do need separate tables, then you might look at GenericForeignKey. This is a mechanism to allow foreign keys to reference objects from different model types. In your case this might look like:
class DistributorGroup(Distributor):
distributor_links = GenericRelation(DistributorLink, related_query_name="distributor_groups")
class DistributorPerson(Distributor):
distributor_links = GenericRelation(DistributorLink, related_query_name="distributor_persons")
class Link(models.Model):
pass
class DistributorLink(models.Model):
link = models.ForeignKey(Link);
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
See the documentation on generic relations for examples and more detail.
Finally, if all else fails, you could indeed create two separate M2M tables for the two kinds of relation.
Note that none of this really has anything to do with abstract models. Abstract models are just a mechanism for code reuse in Django, they don't affect the tables or the queries you run on them.

Independent models relationship

Let's say i have several different models in django project. Now i need to implement reddit-like rating system, that can be easily added to any model in the project. Model look like this:
class Rating(models.Model):
vote = models.IntegerField(blank=False, null=False)
user = models.ForeignKey(User)
The question is - how to connect this 'abstract' model to any other model in project?
You need generic relations from built-in contenttypes framework.
First (and with the disclaimer that I don't know anything about Reddits rating system), unless you want users to put in ratings from negative millions to positive millions, why not use choices?
Now to the problem at hand: A model that is rate-able should have a relation that allows many ratings to one model. Unfortunately this means that none of the relationship fields in Django will work. The absolute simplest solution to this is to have the rating in the actual model.
If you don't want to copy-paste the rating fields you can use an abstract model and inherit from that:
class RateableModel(models.Model):
rating = models.Integerfield(...)
rating_user = models.ForeignKey(User)
class Meta:
abstract = True
class SomeModelThatCanBeRated(RateableModel):
# Fields for this model

Creating several profile classes in django

I'm getting started with django and I'd like to extend the basic django.contrib.auth.models.User class to create my own site profile(s). Here is described how to do it, got that.
As far as I've understood it, you can only specify a single class as AUTH_PROFILE_MODULE in your settings.py.
Now, if I create an extension class of my profile class like this
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
somefield = models.CharField()
class UserProfileExtended(UserProfile):
extrafield = models.CharField()
then I cannot make both of them profile classes, right?
(I know, in this case you'd just add the extrafield to the superclass and drop the UserProfileExtended entirely. Just imagine you have so many fields in UserProfileExtended that you really want to split them up)
Thanks for your help!
There can be only one profile class. I guess I don't understand the scenario where you would want to split them up. In any case,
AUTH_PROFILE_MODULE = "UserProfileExtended"
should handle the inheritance correctly for the simple example you give.

Categories

Resources