how to select columns from multiple models in django? - python

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().

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)

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: Not able to save to DB

I have the following view code:
def control_activation(request, device_id, variable_name, activated):
time_now = int(datetime.utcnow().strftime('%s'))
variable_qs = Variables.objects.filter(device_id=device_id, name=variable_name)
variable = variable_qs[0]
variable.activation = activated
variable.updated_at = time_now
variable.save()
coco_qs = GlobalUpdateTable.objects.all()
coco = coco_qs[0]
coco.variable_udated = time_now
coco.save
return HttpResponse()
For some reason I cannot understand the first save (variable.save) does what is intended but the second one (coco.save) does not.
If I use the following code, on the second part instead of the one above, I am able to save the value to the DB:
GlobalUpdateTable.objects.all().update(variable_updated=time_now)
Both codes should be able to update the column (variable_updated). The table GlobalUpdateTable only has one row, can that constitute a problem in any way?
For reference I indicate the models:
class Variables(models.Model):
name = models.CharField(max_length=20)
device_id = models.ForeignKey(Devices, to_field='id')
device_addr = models.CharField(max_length=6)
device_type = models.CharField(max_length=20)
response_tag = models.CharField(max_length=10)
command = models.CharField(max_length=6)
config_parameter = models.CharField(max_length=6)
unit = models.CharField(max_length=4)
direction = models.CharField(max_length=6)
period = models.IntegerField(null=True, blank=True, default=900)
activation = models.BooleanField(default=False)
formula = models.TextField(null=True, blank=True)
variable_uuid = models.CharField(max_length=36, primary_key=True)
mapping = models.TextField(null=True, blank=True)
updated_at = models.BigIntegerField(default=int(datetime.utcnow().strftime('%s')))
created_at = models.BigIntegerField(default=int(datetime.utcnow().strftime('%s')))
def __unicode__(self):
return unicode(self.device_id) + '_' + unicode(self.name)
class GlobalUpdateTable(models.Model):
device_updated = models.BigIntegerField(default=int(datetime.utcnow().strftime('%s')))
variable_updated = models.BigIntegerField(default=int(datetime.utcnow().strftime('%s')))
It seems you do coco.save instead of coco.save(). No error raised because you don't do anything wrong, but save method hasn't been called.

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

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)

django: How to save value against nested models

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?

Categories

Resources