Ordering a Foreign Key Field by Date Added - django

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.

Related

Django model order the queryset based on booleanfield True/False that related with User FK profile

I have two django models as follows:
The first one is a user profile, which has a FK to User model:
class Profile(models.Model):
PRF_user = models.OneToOneField(User, related_name='related_PRF_user', on_delete=models.CASCADE)
PRF_Priority_Support = models.BooleanField(default=False)
and the second is ticket model which has a FK to User model:
class ticket(models.Model):
ticket_status_options = [
('open', 'open'),
('wait_customer_reply', 'wait_customer_reply'),
('replied_by_staff', 'replied_by_staff'),
('replied_by_customer', 'replied_by_customer'),
('solved', 'solved'),
]
TKT_USER = models.ForeignKey(User, related_name='TKT_USER', on_delete=models.CASCADE)
TKT_DEB = models.ForeignKey('Site_departments', related_name='related_ticket_department', on_delete=models.CASCADE)
TKT_SUB = models.CharField(max_length=50, db_index=True, verbose_name="ticket subject")
TKT_BOD = models.TextField(verbose_name="ticket body")
TKT_image_attachment = models.ImageField(upload_to='TKT_img_attachment', blank=True, null=True , default=None)
TKT_CREATED_DATE = models.DateTimeField(auto_now_add=True)
TKT_UPDATED_DATE = models.DateTimeField(auto_now=True)
I want to sort the tickets based on user profile Priority_Support:
If the user profile PRF_Priority_Support is True, I want to sort it first inside my views QuerySet, otherwise (if PRF_Priority_Support is False) I want to sort it normally.
How can I do this?
You should name your model starting with a capital letter.
And for ordering the tickets, you can use something like this:
' queryset_list = ticket.objects.order_by('-TKT_USER__related_PRF_user__PRF_Priority_Support')
In filtering, when you want to span relationships, you use double underscore __ .
More on this here:
https://docs.djangoproject.com/en/3.1/topics/db/queries/#lookups-that-span-relationships
Another way is adding ordering to your model's Meta class.
For Example:
MyModel(models.Model):
class Meta:
ordering = ('-my_boolean_field ',)
Hi you should filter as follow:
Model.objects.filter(field=True) or False depending on what you need
Regards

How to change the primary key of manytomany table in django

I am changing the primary key of the legacy database. I was able to change the primary key by setting id as the primary key.
Before
class User(models.Model):
name = models.CharField(max_length=5)
email = models.CharField(max_length=5)
age = models.CharField(max_length=5)
After
class User(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=5)
email = models.CharField(max_length=5)
age = models.CharField(max_length=5)
Then
python manage.py makemigrations
python manage.py migrate
This is working fine.
But I also want to change the default primary key of the tables created via ManyToMany feild.
User Model
class User(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=5)
email = models.CharField(max_length=5)
age = models.CharField(max_length=5)
UserProfile Model
class UserProfile(models.Model):
id = models.BigIntegerField(primary_key=True)
address = models.CharField(max_length=5)
father_name = models.CharField(max_length=5)
pincode = models.CharField(max_length=5)
user = models.ManyToManyField(User)
The ManytoMany field creates table called User_user_userprofile with id as Autofield basically previous or default django primary key.
id, user_id, userprofile_id
ManytoMany Table
Now, How to change the primarykey of ManytoMany Feild ie id created by Django?
PS:
Django: 1.11
Python: 2.7.5
DB: Sqlite3 3.7.17 2013-05-20
I stumbled upon this problem today, and ended up solving it by using the through argument of the ManyToManyField. I solved it for Django v3.2.6 however, but the documentation for v1.11 mentions the same behavior for the same argument, so hopefully the solution should work for your version of Django too. Here's the link to the documentation for v1.11 ManyToManyField.through
What the through argument allows you to do is to create the intermediary table (created automatically by ManyToManyField) yourself. You get finer control of how the intermediary table should look like, what fields it should have and what their behavior should be. Hope you are getting a picture.
Let me give you the example of the problem I faced and how I solved it. Hopefully that will make this clearer.
I was trying to establish a many-to-many relationship between two of my existing models.
My first model looks like this,
class BanglaWords(models.Model):
class Meta:
verbose_name_plural = 'Bangla Words'
bng_id = models.CharField(max_length=16, primary_key=True)
bangla_word = models.CharField(max_length=64)
def __str__(self):
return self.bangla_word
and the second one looks like,
class EnglishWords(models.Model):
class Meta:
verbose_name_plural = 'English Words'
eng_id = models.IntegerField(primary_key=True)
word = models.CharField(max_length=64)
bangla_word = models.ManyToManyField(BanglaWords)
def __str__(self):
return self.word
But this resulted in an intermediary table wordnet_englishwords_bangla_word which looked like this,
wordnet_englishwords_bangla_word
id
englishwords_id
banglawords_id
But I didn't want this, I wanted bng_id to be the pk for this table. I solved the problem with ManyToManyField.through as follows,
I defined the intermediary model(table) myself and with the through argument, I pointed to the new intermediary model I created and instructed django to create the table the way I wanted it.
First I created the intermediary model,
class BanglaEnglishRelations(models.Model):
class Meta:
verbose_name_plural = 'Bangla English Relations'
bng_id = models.OneToOneField('BanglaWords', primary_key=True, on_delete=models.CASCADE)
eng_id = models.ForeignKey('EnglishWords', on_delete=models.CASCADE)
which defines bng_id as the primary key as I desired.
Second, I told the ManyToManyField in EnglishWords to base the table on BanglaEnglishRelations like,
bangla_word = models.ManyToManyField(BanglaWords, through=BanglaEnglishRelations)
This resulted in the table wordnet_banglaenglishrelations which looked like,
wordnet_banglaenglishrelations
bng_id_id
eng_id_id
and surved my purposes. You can do something similar to solve your problem and promote whatever field to a pk.

How to create custom relation table for ForeignKey or OnetoOne field?

What I want to do is create a model than can be used to store data about a relation between two elements. With ManytoMany fields, I can use the parameter "through" and specify a model which stores two elements foreign keys as below.
def MyModel(models.Model):
relation = models.ManyToManyField('AnotherModel', through='RelationModel')
def RelationModel(models.Model):
model1 = models.ForeignKey('MyModel')
model2 = models.ForeignKey('AnotherModel')
slug = models.CharField()
What would be the equivalent for a OnetoOne relation or a ForeignKey relation ? I've read the docs about custom managers and some posts on SO so in the end I'm quite confused and I dont know what is the solution. Thanks in advance for any help.
you can do like this
from products.models import VendorDetails
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE)
user_location = models.CharField(max_length=50, null=True)
vendor_category = models.ManyToManyField(VendorDetails, through="UserProfileVendorCategory")
class UserProfileVendorCategory(models.Model):
user_profile = models.ForeignKey(UserProfile)
vendor_category = models.ForeignKey(VendorDetails)
location = models.CharField(max_length=256)

Django adding multiple records with the same foreign key in ModelAdmin

Suppose I have the following two models task and person.
Now each person can have multiple tasks (one to many relationship).
Now in the admin app for a person I can only add one foreign key per record thus I'll have to create multiple records for a person having a different task but the same email and name fields.
Is there anything I can do in personAdmin that would allow me to add multiple foreign keys for the same person and in the backend it would create multiple records ?
class task(models.Model):
description = models.CharField(max_length=100)
class person(models.Model):
task = models.ForeignKey(Author, on_delete=models.CASCADE)
email =models.CharField(max_length=100)
name = models.CharField(max_length=100)
class personAdmin(admin.ModelAdmin):
pass
You could add a third table with both the first two tables as FOREIGN KEY.
So this is what you have currently
class ToDo_Task(models.Model):
description = models.CharField(max_length=100)
class User(models.Model):
task = models.ForeignKey(Author, on_delete=models.CASCADE)
email =models.CharField(max_length=100)
name = models.CharField(max_length=100)
Adding a third table
class person_task(models.Model):
task = models.ForeignKey(ToDo_Task, on_delete = models.CASCADE)
person = models.ForeignKey(User, on_delete = models.CASCADE)
...
You may add even more fields in the new table.

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.