Multiple foreign keys to the same id. Django. Design Patterns - python

I really can't figure out why I can't point by Foregin Key the exactly same id multiple times.
I'm trying to use Django ORM to the database that already exists.
And it looks like this:
I wanted to create model according to that:
class TestID(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=250)
test_case_id = models.CharField(max_length=250, unique=True)
module = models.CharField(max_length=50)
full_description = models.TextField()
class Meta:
db_table = "TestID"
class TestCaseRun(models.Model):
id = models.AutoField(primary_key=True)
soft_version = models.CharField(max_length=50)
automated_test_case_version = models.CharField(max_length=50, unique=True)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
checksum = models.CharField(max_length=250)
result = models.CharField(max_length=50)
test_case_id = models.ForeignKey(TestID, db_column='test_case_id')
class Meta:
db_table = "TestCaseRun"
class TestStep(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=250, null=False)
result = models.CharField(max_length=50)
description = models.CharField(max_length=250)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
test_case = models.ForeignKey(TestCaseRun, db_column='id')
class Meta:
db_table = "TestStep"
class single_check(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=250)
comparison = models.CharField(max_length=5, null=False)
expected = models.CharField(max_length=50, null=False)
actual = models.CharField(max_length=50, null=False)
result = models.CharField(max_length=50)
comment = models.CharField(max_length=250)
event_time = models.DateTimeField()
test_step_id = models.ForeignKey(TestStep, db_column='id')
class Meta:
db_table = "single_check"
class action(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=250)
type = models.CharField(max_length=5, null=False)
result = models.CharField(max_length=50)
comment = models.CharField(max_length=250)
event_time = models.DateTimeField()
test_step_id = models.ForeignKey(TestStep, db_column='id')
class Meta:
db_table = "action"
class logs(models.Model):
id = models.AutoField(primary_key=True)
msg = models.CharField(max_length=350)
type = models.CharField(max_length=5, null=False)
result = models.CharField(max_length=50)
comment = models.CharField(max_length=250)
event_time = models.DateTimeField()
test_step_id = models.ForeignKey(TestStep, db_column='id')
class Meta:
db_table = "logs"
When I try to run that code I get errors:
ERRORS:
web_report.TestStep: (models.E007) Field 'test_case' has column name 'id' that is used by another field.
HINT: Specify a 'db_column' for the field.
web_report.action: (models.E007) Field 'test_step_id' has column name 'id' that is used by another field.
HINT: Specify a 'db_column' for the field.
web_report.logs: (models.E007) Field 'test_step_id' has column name 'id' that is used by another field.
HINT: Specify a 'db_column' for the field.
web_report.single_check: (models.E007) Field 'test_step_id' has column name 'id' that is used by another field.
HINT: Specify a 'db_column' for the field.
And I really can not figure out why I can't point by Foregin Key the exactly same id multiple times. Imho nothing is wrong with this design. But I'm beginner in relational database design.

It looks like you are using the db_column argument incorrectly. This is the field on the model that you are linking from, not the column on the model that you are linking to. You cannot use db_column='id', because there is already a primary key id for each model.
Taking your TestStep model as an example:
class TestStep(models.Model):
id = models.AutoField(primary_key=True)
...
test_case = models.ForeignKey(TestCaseRun, db_column='id')
Your diagram shows that it is the test_case_id column that links to the TestCase model. So you should have:
test_case = models.ForeignKey(TestCaseRun, db_column='test_case_id')
or because that is the default, simply
test_case = models.ForeignKey(TestCaseRun)

Related

How to get table data (including child table and sub child data) based on id which obtains from another table data? Django

views
company = Company.objects.get(id = company_id) # getting input from django urls (<int:company_id>)
vehicles = CompanyContainVehicles.objects.filter(company_id=company.id) # Give all rows having same id (company.id)
all_vehicles = Vehicle.objects.filter(companies=company) # Gives all row with id provide by company
all_vehicles_parts = VehiclePart.objects.filter(__________) # Not Working
models
class Company(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True, unique=True)
description = models.TextField()
class Vehicle(models.Model):
vehicle_number = models.IntegerField()
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True, unique=True)
companies = models.ManyToManyField(
Company,
through='CompanyVehicle',
related_name='companies'
)
class CompanyVehicle(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class VehiclePart(models.Model):
id = models.AutoField(primary_key=True)
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
type = models.ForeignKey(PartType, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
How do I get VehiclePart's with their Vehicle? (I think I will give all the data in a variable and we should divide it and add it with their Vehicle). Also, what can we do to access data if VehiclePart contains a child class named VehiclePartDetail?
I think I will give all the data in a variable and we should divide it and add with their Vehicle.
You don't have to. Django can read ForeignKey relations in reverse. You can query with:
qs = Vehicle.objects.prefetch_related('vehiclepart_set')
then you can enumerate over the queryset, and for each Vehicle object, access this with .vehiclepart_set.all(). For example:
for item in qs:
print(vehicle_name)
for part in item.vehiclepart_set.all():
print(part.id)

Django ORM multiple inner join in query

I want to be able to do queries involving multiple inner joins using Django ORM, here's my model (showing only relevant fields)
class Students(models.Model):
class Status(models.IntegerChoices):
preRegistered = 0 #No ha aceptado terminos y condiciones
Enabled = 1
Disabled = 2
Suspended = 3
Test = 4
id = models.AutoField(primary_key=True)
user = models.ForeignKey(Users, on_delete=models.CASCADE)
trainingPath = models.ForeignKey(trainingPaths, on_delete=models.CASCADE)
status = models.IntegerField(choices=Status.choices, default=0)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Students'
class trainingPaths(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=70, blank=False, null=False)
shortName = models.CharField(max_length=10, blank=True)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Training_Path'
class Courses(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=70, blank=False, null=False)
path = models.URLField(max_length=500, blank=True, null=True)
shortName = models.CharField(max_length=6, blank=True)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
course_image = models.URLField(max_length=200, blank=True)
class Meta():
db_table = 'Courses'
class CoursesXTrainingP(models.Model):
id = models.AutoField(primary_key=True)
trainingPath = models.ForeignKey(trainingPaths, on_delete=models.CASCADE)
course = models.ForeignKey(Courses, on_delete=models.CASCADE)
alternativeName = models.CharField(max_length=70, blank=True)
order = models.PositiveIntegerField(blank=False)
creationDate = models.DateTimeField(auto_now_add=True)
modificationDate = models.DateTimeField(auto_now=True)
class Meta():
db_table = 'Courses_X_Training_Paths'
I want to get the information of the courses that a student has according to the value of the "trainingPath".
this is my SQL query
select
courses.id, courses.`name`, courses.course_image
from
students
join
courses_x_training_paths
on
students.trainingPath_id = courses_x_training_paths.trainingPath_id
join
courses
on
courses_x_training_paths.course_id = courses.id
where
students.trainingPath_id=1;
I have tried several ways and none of them have worked, could you please help me?
You can filter with:
Courses.objects.filter(
coursesxtrainingp__trainingPath_id=1
)
The join on the Students model is not necessary, since we already know that the trainingPath_id is one by filtering on the CoursesXTrainingP model.
Note: normally a Django model is given a singular name, so Student instead of Students.
Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: modification_date instead of modificationDate.

when in try to access mysql view using django model it throws an error

I want to access the records in mysql view using django filter but it throws an error
class PartnerPayBillSummaryDetails(models.Model):
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = '66_1_partner_pay_bill_ageing_dtl'
try:
p = PartnerPayBillSummaryDetails.objects.all()
print(p)
except Exception as e:
print(e)
Error:
OperationalError: (1054, "Unknown column '66_1_partner_pay_bill_ageing_dtl.id' in 'field list'")
I figured out the answer
it requires a filed as a primary key. I solve this by adding
"primary_key=True" in invoice_id
invoice_id = models.IntegerField(primary_key=True)
In my opinion it is looking for a primary key called 'id' (by default if you don't define). Also your db_table name in meta class is starting with a number. Not sure it will allow that. I am away from computer to test it out but based on guess, I have two solutions for you. Please try them in that order. All I have done is change your model class in both the solutions.
class PartnerPayBillSummaryDetails(models.Model):
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = 'partner_pay_bill_ageing_dtl_66_1'
Solution 2
class PartnerPayBillSummaryDetails(models.Model):
id = models.AutoField(primary_key=True)
invoice_no = models.CharField(max_length=200)
invoice_id = models.IntegerField()
partner_id = models.IntegerField()
partner_name = models.CharField(max_length=100)
status = models.CharField(null=False, max_length=50)
invoice_date = models.DateField()
bill_received_date = models.DateField()
due_date = models.DateField()
due_date_ageing = models.IntegerField()
payable_amount = models.DecimalField(max_digits=20, decimal_places=2, default=0)
class Meta:
managed = False
db_table = 'partner_pay_bill_ageing_dtl_66_1'
Please let me know if there is still some error.
You have to add primary key to the model.
id = models.AutoField(primary_key=True)
or make any column the primary key like:
invoice_id = models.IntegerField(primary_key=True)

Django-tables2: How to use accessor to bring in foreign columns?

I've tried reading the docs and previous answers to this question without much luck.
I've got a bunch of student-course registrations and I'd like to see some of those selected registrations in conjunction with some of the attributes of the students. No luck so far...I'd request your advice!
Here's the model:
class Student(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
netID = models.CharField(max_length=8)
class Registration(models.Model):
student = models.ForeignKey(Student)
course = models.ForeignKey(Course)
attendance_M = models.BooleanField(default=False)
attendance_Tu = models.BooleanField(default=False)
and here is the tables.py:
class AttendanceTable(tables.Table):
netID = tables.Column(accessor='Student.netID')
first = tables.Column(accessor='Student.first_name')
last = tables.Column(accessor='Student.last_name')
class Meta:
model = Registration
attrs = {"class": "paleblue"}
fields = ('attendance_M', 'attendance_Tu',)
sequence = ('netID', 'first', 'last', 'attendance_M', 'attendance_Tu',)
While I'm getting data on the attendance values, there's nothing from the student foreign columns.
netID First Last Attendance M Attendance Tu
— — — ✔ ✘
And it's the same deal if I start the Table with model = Student and use accessors against the Registration table, it's the same deal.
I feel like I'm missing something very conceptual and crucial -- please guide me!
The model name in the accessor parameter of the column should be lowercase.
Use accessor='student.netID' instead of accessor='Student.netID'.
When using the accessor parameter, you have to use the field name stated in the Model that has the foreign key, and then select which field from that table you want to use.
So, for these models:
#models.py
class Description_M(models.Model):
id_hash = models.CharField(db_column='Id_hash', primary_key=True, max_length=22)
description = models.CharField(db_column='Description', max_length=255, blank=True, null=True)
class GeoCodes(models.Model):
geo = models.CharField(db_column='Geo', primary_key=True, max_length=5)
city_name = models.CharField(db_column='City', max_length=150, blank=True, null=True)
class RefSources(models.Model):
id_source = models.IntegerField(db_column='Id_source', primary_key=True,)
source_name = models.CharField(db_column='Source', max_length=150, blank=True, null=True)
class Price(models.Model):
id_hash = models.ForeignKey(Description_M, models.DO_NOTHING, db_column='Id_hash')
date= models.ForeignKey(DateTime, models.DO_NOTHING, db_column='Date')
geo = models.ForeignKey(GeoCodes, models.DO_NOTHING, db_column='Geo')
id_source = models.ForeignKey(RefSources, models.DO_NOTHING, db_column='Id_source') # Field name made lowercase.
price = models.FloatField(db_column='Price',primary_key=True, unique=False,default=None)
When using the foreign key to pull fields from that table, you have to:
class price_table(tables.Table):
description = tables.Column(accessor = 'id_hash.description')
city = tables.Column(accessor = 'geo.city_name')
source = tables.Column(accessor = 'id_source.source_name')
class Meta:
model = Price
fields = ['date','price']
sequence = ['description ','date','city ','source','price']
template_name = 'django_tables2/bootstrap.html'

django join query

Im new to django. I have this model, In tblperson, only the forgein keys of type and status are saved. How do I join all tables to display their value not their forgein key? For example.
TblPerson.objects.raw('SELECT * FROM "Tblperson" INNER JOIN "Tblstatus" ON ("TblPerson"."Status" = "Tblstatus"."ID")'):
Thanks.
class TblPerson(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'ID')
Type = models.IntegerField(null=True, db_column=u'Type', blank=True)
Status = models.IntegerField(null=True, db_column=u'Status', blank=True)
class Meta:
db_table = u'tblPerson'
class Tblstatus(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'statStatusID')
Status = models.CharField(max_length=25, db_column=u'statStatus', blank=True)
class Meta:
db_table = u'tblStatus'
class Tbltype(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'typTypeID')
Type = models.CharField(max_length=25, db_column=u'typType', blank=True)
class Meta:
db_table = u'tblType'
The power of Django is in the ORM, which means you should be writing very little SQL if at all.
class Person(models.Model):
#don't use this because id is generated automatically
#ID = models.AutoField(primary_key=True, db_column=u'ID')
type = models.ForeignKey(Type)
status = models.ForeignKey(Status)
#Type,Status analogous
#filter like this
selected = Person.objects.filter(type=SomeType)
for p in selected:
print p.id,p.type,p.status
I would suggest you to re-write your models. So, that your TblPerson has a many to one relationship with Tblstatus
class TblPerson(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'ID')
Type = models.IntegerField(null=True, db_column=u'Type', blank=True)
Status = models.ForeignKey(Tblstatus, null=True, db_column=u'Status', blank=True)
class Meta:
db_table = u'tblPerson'
class Tblstatus(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'statStatusID')
Status = models.CharField(max_length=25, db_column=u'statStatus', blank=True)
class Meta:
db_table = u'tblStatus'
Using this you would be able to query for TblPerson objects for which Tblstatus exists like this
TblPerson.objects.filter(Status__isnull=False)

Categories

Resources