How to specify the many to one models in django? - django

I'm trying to link two models: Department and User. They have a many-to-one relation.
A department can have only admin (User) and a department can have many users.
A User can only be in one department.
Here is my code
class Department(models.Model):
admin = models.ForeignKey("applications.User", blank=True, null=True, on_delete=models.SET_NULL)
class User(AbstractUser, models.Model):
username = models.CharField(max_length=32, unique=True)
department = models.ForeignKey(Department, null=True, on_delete=models.SET_NULL, related_name="members")
But I'm having this error:
ERRORS:
applications.Department.admin: (fields.E303) Reverse query name for 'Department.admin' clashes with field name 'User.department'.
HINT: Rename field 'User.department', or add/change a related_name argument to the definition for field 'Department.admin'.
I need to keep attributes naming as is.
How to properly fix and model the relation between the tables?
Is django assuming that Department may have many admins?

Related

Template tag for going from model1 to model2 that has foreign key to model1

Is there a template tag or a way that I can go from my main model to a specific model that has a foreign key to my main model?
models.py
class BillingAddress(models.Model):
user = models.ForeignKey(UserCart, on_delete=models.CASCADE)
address1 = models.CharField(max_length=120, null=True)
class HomeAddress(models.Model):
user = models.ForeignKey(UserCart, on_delete=models.CASCADE)
address1 = models.CharField(max_length=120, null=True)
class UserCart(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
I want to get the 'address1' field from the BillingAddress that is related to a usercart. I don't think that I can use {{usercart.address1}} as both HomeAddress and BillingAddress have a field called address1 and are related to the usercart.
Thanks!
Dont worry, you can get it normally. Because BillingAddress and HomeAddress FK to UserCart.This mean from UserCart, you have 2 set different is usercart.billingaddress_set and usercart.homeaddress_set. This is 2 list of BillingAddress and HomeAddress related with UserCart.
If you want get one address1 field. You must know what set you want get it. Like example : usercart.billingaddress_set.first().address1 will give you first record which BillingAddress related with UserCart.
If you still worry, you can change name of billingaddress_set or homeaddress_set by related_name to anything name you want. Read related_name for more information

Multiple ForeignKeys in Through model for Many-to-many relation to same model

I've got a many-to-many relation from a model called Resource to itself through an intermediary model called RelatedResource:
class Resource(TimeStampedModel):
title = models.CharField(max_length=100, unique=True) # book title, person's name, video title, etc.
description = models.TextField(max_length=500, null=True, blank=True)
link = models.URLField(max_length=500, blank=True, null=True) # dynamically generated for youtube and amazon; todo: uniqueness
resourceID = models.CharField(max_length=20, blank=True, null=True) # todo: uniqueness
picture = models.URLField(max_length=500, blank=True)
tags = TaggableManager()
...
class RelatedResource(models.Model):
input = models.ForeignKey(Resource, related_name="input_resource")
output = models.ForeignKey(Resource, related_name="output_resource")
input_affiliate = models.ForeignKey(Resource, related_name="while_with", blank=True, null=True)
reason = models.CharField(max_length=500)
...
Django complains that having more than 2 foreign keys to Resource is ambiguous, of course, because then it doesn't know which two of the three ForeignKey fields apply in the many-to-many relation.
Is there any way I can keep all 3 ForeignKey fields in the intermediary model and tell Django which 2 are meant for the many-to-many relation?
I think what you are trying to do is recursive relationship.
It is described in here.
https://docs.djangoproject.com/en/1.6/ref/models/fields/#recursive-relationships
And here.
Django recursive relationship

Django model with Foreign Key and ManyToMany relations to same model

I have a django model as follows:
class Subscription(models.Model):
Transaction = models.ManyToManyField(Transaction, blank=True, null=True)
User = models.ForeignKey(User)
...etc...
I am trying to add a ManyToMany field to the User model as follows:
SubUsers = models.ManyToManyField(User, blank=True, null=True)
but I get this error when I run syncdb:
AssertionError: ManyToManyField(<django.db.models.fields.related.ForeignKey object at 0x19ddfd0>) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string 'self'
If I encase User in quotes, I get instead:
sales.subscription: 'User' has a relation with model User, which has either not been installed or is abstract.
I know the User model is imported correctly. Any ideas why having 2 fields pointing to the User model causes problems? Thanks in advance...
The reason why it fails is because the name of your field is the same as the class name (User). Use lowercase field names, it the standard convention in Django and Python. See Django Coding style
Also, you need to add a related_nameparameter to your relationship:
class Subscription(models.Model):
user = models.ForeignKey(User)
sub_users = models.ManyToManyField(User, blank=True, null=True, related_name="subscriptions")

Ordering a Foreign Key Field by Date Added

I have the following two models:
class Position(models.Model):
position = models.CharField(max_length=100)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
positions = models.ManyToManyField(Position, blank=True, null=True)
This creates a database table called userprofile_userprofile_positions, with the following three columns:
id
userprofile_id
position_id
How would I add a fourth field to this table --
created_at = models.DateTimeField(auto_now_add=True)
I would like to do this through django, if possible. Thank you.
Create a new model and specify it in the through attribute of your ManyToMany. The Django docs have a section on this exact use case: Extra fields on many-to-many relationships.

how to design model for my case with django?

Here are two roles: Trainer and Trainee. Trainer may have multiple trainees. While each trainee may have only one trainer or have no trainer.
Here is my model:
class TrainerShip(models.Model):
trainer = models.ForeignKey('Trainer')
trainee = models.ForeignKey(User)
request_date = models.DateTimeField(auto_now_add=True)
accept_date = models.DateTimeField(auto_now_add=True)
expiration_date = models.DateTimeField(auto_now_add=True)
class Trainer(models.Model):
user = models.ForeignKey(User, unique=True)
trainee = models.ManyToManyField(User, through=TrainerShip)
introduction = models.TextField(max_length=500)
certification = models.TextField(max_length=300)
specialties = models.TextField(max_length=300)
contact = models.TextField(max_length=100)
active = models.BooleanField(default=False)
I was getting following error when trying to create db:
shen#shen-laptop:~/django/sutifang$ ./manage.py syncdb
Error: One or more models did not validate:
registration.trainer: Accessor for field 'user' clashes with related m2m field 'User.trainer_set'. Add a related_name argument to the definition for 'user'.
registration.trainer: Accessor for m2m field 'trainee' clashes with related field 'User.trainer_set'. Add a related_name argument to the definition for 'trainee'.
Anyone has the idea to solve this problem? Is there a better way to model this kind of relationship?
The problem is that a Foreign key established a bidirectional relationship. This means you can do User.trainer_set to get all of the Trainer models under a User, which means you have a circular reference back to the user database (getting the Trainer models gets all of its fields, one of those fields being the original User model.
So, to fix this, add a related name argument to the Foreign key to stop this circular dependency:
user = models.ForeignKey(User, unique=True, related_name='traineruser')
You can replace traineruser with something that does not already have a table in the database.