I have models with nested many-to-many relationships
IndependentTest have many-to-many relationship with Protocols
and Protocols have many-to-many relationship with Format.
So I need to save test results for a particular User against IndependentTests.
EDIT: Here are the models
class IndependentTest(models.Model):
name = models.CharField(max_length=1000)
choice = models.ManyToManyField(to=TestChoice, null=True, blank=True)
required = models.BooleanField()
testType = models.CharField(max_length=200,
choices=Values.CUSTOM_ATTRIB_TYPES)
class TestProtocol(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=1000)
independent_test = models.ManyToManyField(IndependentTest,
through='PIOrder')
class PIOrder(models.Model):
protocol = models.ForeignKey(TestProtocol)
independent = models.ForeignKey(IndependentTest)
order = models.IntegerField()
class TestFormat(models.Model):
name = models.CharField(max_length = 100)
test_protocol = models.ManyToManyField(TestProtocol, through='FPOrder')
class FPOrder(models.Model):
format = models.ForeignKey(TestFormat)
protocol = models.ForeignKey(TestProtocol)
order = models.IntegerField()
EDIT: I don't know if this is a good approach, but I can make a new class
class CandidateTest (models.Model):
test_value = models.CharField(max_length = 200)
candidate = models.ForeignKey(Candidate)
test = models.ForeignKey(IndependentTest)
testProtocol = models.ForeignKey(TestProtocol)
testFormat = models.ForeignKey(TestFormat)
Although the results will be saved in test_value but what about any other data like the date or place the test was taken?
Related
model.py
class LabTable(models.Model):
LabNo = models.AutoField(primary_key=True)
Pid = models.IntegerField()
Weight = models.IntegerField()
DoctorId = models.ForeignKey(DoctorTable,on_delete=models.CASCADE)
Date = models.DateField()
Category = models.CharField(max_length=50)
PatientType = models.CharField(max_length=50)
Amount = models.IntegerField()
class DoctorTable(models.Model):
DoctorId = models.AtuoField(primary_key = True)
DoctorName = models.CharField(max_length = 50)
Department = models.CharField(max_length = 100)
1.Here, I have created the lab model and a foreign key with doctor table. I want to use doctor table to present data in dropdown.
You can specify how to show a DoctorTable model object by implementing the __str__ method for that model, so:
class DoctorTable(models.Model):
DoctorId = models.AutoField(primary_key=True)
DoctorName = models.CharField(max_length=50)
Department = models.CharField(max_length=100)
def __str__(self):
return self.DoctorName
Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: doctor_name instead of DoctorName.
Note: Models normally have no Table suffix. A model is not a table, it is stored in a relational database as a table, but even then it has extra logic like validators, managers, etc.
I am Developing a E-commerce Application with Django
So what I was thinking is getting the category of the Product in a separate Model and list them down in another using choice field in CharField.
So Here is the code for this
This is the model for getting the Categories from the user
class ProjektCat(models.Model):
id = models.AutoField(primary_key=True)
Option_Name = models.CharField(max_length=50)
Option_Number = models.IntegerField()
Number_Visits = models.IntegerField(default=0)
def __str__(self):
return f'{self.Option_Name}'
and here is the code to list those categories as a dropdown in the CharField
class Software_And_Service(models.Model):
id = models.AutoField(primary_key=True)
Product_Name = models.CharField(max_length=100, default='')
projectKats = ProjektCat.objects.all()
choice = []
for i in projectKats:
option = (i.Option_Number, i.Option_Name)
choice.append(option)
Cateogary = models.CharField(
max_length=256, choices=choice)
Price = models.IntegerField(default=0)
Description = models.TextField(default='', max_length=5000)
pub_date = models.DateField(auto_now_add=True, blank=True, null=True)
image = models.URLField(default='')
linkToDownload = models.URLField(default='')
def __str__(self):
return f'Projekt : {self.Product_Name}'
But it's Showing me an Error that there is no such table in app_name.projektcat
Is there is any solution for this??
It's not how you do this. First correctly assign the projectKats field i.e
# You can set max_length as per your choice
projectKats = models.CharField(max_length=50)
You need to do this logic in django forms rather than django models.
So this is how you can do it.
forms.py
from django import forms
from .models import ProjektCat, Software_And_Service
def get_category_choices():
return [(obj.Option_Name,obj.Option_Name) for obj in ProjektCat.objects.values_list('Option_Name',flat=True).distinct()]
class SoftwareAndServiceForm(forms.ModelForm):
projectKats = forms.ChoiceField(choices=get_category_choices)
class Meta:
model = Software_And_Service
fields = [
'projectKats',
# whatever fields you want
]
CHOICES = (('Earned Leave','Earned Leave'),('Casual Leave','Casual Leave'),('Sick Leave','Sick Leave'),('Paid Leave','Paid Leave'))
STATUS_CHOICES = (('0', 'Rejected'),('1', 'Accepted'),)
class Leave(models.Model):
employee_ID = models.CharField(max_length = 20)
name = models.CharField(max_length = 50)
user = models.ForeignKey(User, on_delete = models.CASCADE, null =True)
type_of_leave = models.CharField(max_length = 15, choices = CHOICES)
from_date = models.DateField()
to_date = models.DateField()
status = models.CharField(max_length = 15, choices = STATUS_CHOICES)
class History(models.Model):
name = models.CharField(max_length = 50)
employee_ID = models.CharField(max_length = 20)
earned_leave = models.IntegerField()
casual_leave = models.IntegerField()
sick_leave = models.IntegerField()
paid_leave =models.IntegerField()
def __str__(self):
return self.name
I want to store the values name and employee_ID from model Leave into the model History only after the status == 1. I'm pretty new to django, help me with this.
If you want to relate a model to another model then based on relation you can use OneToOneField, ManyToManyField, ForeignKey, etc
Here what you have done is that you have a model Leave with Fields employee_ID, name and user
Another model History with fields employee_ID, name, user (inherited from Leave) and emp_ID, full_name. This is just extending that model class and creating new model objects. Both will remain unrelated only. (I don't have enough experience to tell you exact/detailed behaviour)
So, for you case you can have a OneToOneField(or something else based on your business logic) from history model to leave model something like this.
class Leave(models.Model):
employee_ID = models.CharField(max_length = 20)
name = models.CharField(max_length = 50)
user = models.ForeignKey(User, on_delete = models.CASCADE, null =True)
class History(models.Model):
emp_ID = models.CharField(('employee ID'),max_length = 25)
full_name = models.CharField(('Name'),max_length = 40)
leave = models.OneToOneField(Leave, on_delete = models.SET_NULL)
Then you can save your data as follows :
# I am assuming you're inside some view and you want to create leave for the user who is logged in, refactor based on your requirements
leave = Leave.objects.create(employee_ID="EMPLOYEEID", name="EMPLOYEENAME", user=request.user)
# here pass the leave that we have created previously
history = History.objects.create(emp_ID="EMPLOYEEID", full_name="EMPLOYEEFULLNAME", leave=leave)
I am assuming you're having leave start and end datetime field also. I think you should also look into why employee ID is repeated in both models.
Let me know if you have any doubts/queires. Thanks~
I have this model in models.py:
class Foo(models.Model):
bar = models.ManyToManyField('self')
How can I serialize it?
I was using one of solutions from this topic: Django rest framework nested self-referential objects But none of them working with M2M, either causes in infinity cycle of serialization. Solution where I'm using a row of serializers works good except it's limited by copy&paste (sounds really sad :) )
Generic model mostly looks like a comment's tree. I hope such a problem was already solved before but haven't found how yet.
I don't think you will get a straight solution to this, so try this
class FooBaseSerializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
model = Foo
class FooSerializer(FooBaseSerializer):
bar = FooBaseSerializer(many=True)
NOTE: As a Software Engineer, I love to use Architectures and I have deeply worked on Layered Approach for Development so I am gonna be Answering it with Respect to Tiers.
I would suggest the use of a Bridge Table for M2M relationships to Normalize Stuff. Anyhow serializing many of the Items would require to
serializer = SerializerNameGoesHere(AllFilteredObjectsfromModel, many=True)
would serializer m2m.
Here's an Example in Layered Approach!
As i understood the Issue, Here's the Solution
models.py
class Member(models.Model):
member_id = models.AutoField(primary_key=True)
member_name = models.CharField(max_length =
class Group(models.Model):
group_id = models.AutoField(primary_key=True)
group_name = models.CharField(max_length = 20)
fk_member_id = models.ForeignKey('Member', models.DO_NOTHING,
db_column='fk_member_id', blank=True, null=True)
class Membership(models.Model):
membershipid = models.AutoField(primary_key=True)
fk_group_id = models.ForeignKey('Group', models.DO_NOTHING,
db_column='fk_member_id', blank=True, null=True)
join_date = models.DateTimeField()
serializers.py
import serializer
class AllSerializer(serializer.Serializer):
group_id = serializer.IntegerField()
group_name = serializer.CharField(max_length = 20)
join_date = serializer.DateTimeField()
CustomModels.py
imports...
class AllDataModel():
group_id = ""
group_name = ""
join_date = ""
BusinessLogic.py
imports ....
class getdata(memberid):
alldataDict = {}
dto = []
Member = models.Members.objects.get(member_id=memberid) #or use filter for Name
alldataDict["MemberId"] = Member.member_id
alldataDict["MemberName"] = Member.member_name
Groups = models.Group.objects.filter(fk_member_id=Member)
for item in Groups:
Custommodel = CustomModels.AllDataModel()
Custommodel.group_id = item.group_id
Custommodel.group_name = item.group_name
Membership = models.Membership.objects.get(fk_group_id=item.group_id)
Custommodel.join_date = Membership.join_date
dto.append(Custommodel)
serializer = AllSerializer(dto,many=True)
alldataDict.update(serializer.data)
return alldataDict
models.py
class Custom_user_model(User):
daily_target = models.IntegerField()
monthly_target = models.IntegerField()
yearly_target = models.IntegerField()
weekly_target = models.IntegerField()
call_target = models.IntegerField()
email_target = models.IntegerField()
meeting_target = models.IntegerField()
added_under = models.IntegerField()
profile_pic = models.TextField()
doj = models.DateTimeField(default='')
location_id = models.IntegerField()
locked = models.BooleanField()
default_currency = models.IntegerField()
date_change_permission = models.BooleanField()
deal_back_log = models.BooleanField()
created_date=models.DateTimeField(auto_now_add=True)
role_id=models.ForeignKey('user_Roles')
profile_pic = models.FileField(upload_to='.')
objects = UserManager()
class Deal(models.Model):
a_choices = ((0,'yes'),(1,'no'))
approved = models.IntegerField(choices=a_choices,default=1)
user_id = models.ForeignKey('Custom_user_model')
company_id = models.IntegerField()
contact_id = models.IntegerField()
deal_title=models.CharField(max_length=200)
deal_value = models.CharField(max_length=20)
currency_id = models.IntegerField()
process_id = models.IntegerField()
expected_close_date = models.DateField(default='')
closed_date = models.DateField()
deal_milestone=models.IntegerField()
created=models.DateTimeField(auto_now_add=True)
last_modified=models.DateTimeField(auto_now_add=True)
s_choices = ((0,'active'),(1,'won'),(2,'junk'),(3,'lost'))
status = models.IntegerField(choices=a_choices,default=0)
type = models.CharField(max_length=50, default='deal')
class user_Roles(models.Model):
code = models.CharField(max_length=20)
description = models.CharField(max_length=30)
permitted_menus = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
views.py
Here, i wrote the code to get columns from three models. But
Deal.objects.filter(user_id__role_id_id=1).select_related() returned nothing and Deal.objects.filter(user_id__role_id_id=1).select_related().values() returned the fields from deal model only. It shows 'no fields error', when specifying relationship as values('Custom_user_model__doj').How can i select fields from multiple models?
def get_all_normal_users(request,start_date=None,end_date=None):
query = Deal.objects.filter(user_id__role_id_id=1).select_related().values()
start_date_range = (
# The start_date with the minimum possible time
datetime.datetime.combine(start_date, datetime.time.min),
# The start_date with the maximum possible time
datetime.datetime.combine(end_date, datetime.time.max)
)
query = query.filter(created__range=start_date_range).values()
data_dict = ValuesQuerySetToDict(query)
data_json = json.dumps(data_dict)
return json_response({'status':data_json})
If you want to select related values you have to specify all parameters you want in values(). Otherwise you will get only the foreignkey to your user model. Try adding the values you want from your user model with __:
query = query.filter(created__range=start_date_range).values('approved', ..., 'user_id__daily_target', 'user_id__username')
Btw if you are creating an API you should have a look at django-rest-framework
try this,
Deal.objects.filter(user_id__role_id_id=1, created__range=start_date_range).select_related('user_id').values()
or specify required fields as parameters to values().