While trying to run my second Django 2.1 /Postgres 10 project I got stuck with the following programming error:
ProgrammingError at /admin/vocs_app/subsubscriber/
column sub_subscriber.sub_prev_sst_uid_id does not exist
LINE 1: ...", "sub_subscriber"."sub_next_recharge_datetime", "sub_subsc...
^
HINT: Perhaps you meant to reference the column "sub_subscriber.sub_prev_sst_uid".
I can open the admin app of my application, i.e., 127.0.0.1:8000/admin/vocs_app.
It lists all imported models from my database; to illustrate my case I believe the following classes are sufficient:
(taken from my_site/vocs_app/models.py:)
from django.db import models
class VneVirtualNetwork(models.Model):
vne_uid = models.BigAutoField(primary_key=True)
vne_nop_uid = models.ForeignKey(NopNetworkOperator, models.DO_NOTHING, db_column='vne_nop_uid')
vne_name = models.CharField(max_length=50)
vne_code = models.CharField(max_length=50)
vne_external_id = models.CharField(max_length=100, blank=True, null=True)
vne_idd_code = models.CharField(max_length=5)
vne_sn_length = models.IntegerField()
createdon = models.DateTimeField()
createdby = models.CharField(max_length=150)
createdfrom = models.CharField(max_length=150)
modifiedon = models.DateTimeField()
modifiedby = models.CharField(max_length=150)
modifiedfrom = models.CharField(max_length=150)
class Meta:
managed = False
db_table = 'vne_virtual_network'
class SstSystemStatus(models.Model):
sst_uid = models.BigAutoField(primary_key=True)
sst_name = models.CharField(max_length=50)
sst_description = models.CharField(max_length=100, blank=True, null=True)
startdate = models.DateField(blank=True, null=True)
enddate = models.DateField(blank=True, null=True)
class Meta:
managed = False
db_table = 'sst_system_status'
class SubSubscriber(models.Model):
sub_uid = models.BigAutoField(primary_key=True)
sub_vne_uid = models.ForeignKey('VneVirtualNetwork', models.DO_NOTHING, db_column='sub_vne_uid')
sub_rpl_uid = models.ForeignKey(RplRatePlan, models.DO_NOTHING, db_column='sub_rpl_uid')
sub_account_user_id = models.CharField(max_length=100, blank=True, null=True)
sub_external_id = models.CharField(max_length=100)
sub_hzn_uid = models.ForeignKey(HznHomezoneName, models.DO_NOTHING, db_column='sub_hzn_uid')
sub_low_balance_trigger = models.BooleanField()
sub_first_call_datetime = models.DateTimeField(blank=True, null=True)
sub_last_enabled_datetime = models.DateTimeField(blank=True, null=True)
sub_last_disabled_datetime = models.DateTimeField(blank=True, null=True)
sub_last_recharge_datetime = models.DateTimeField(blank=True, null=True)
sub_next_recharge_datetime = models.DateTimeField(blank=True, null=True)
sub_prev_sst_uid = models.ForeignKey(SstSystemStatus, related_name='sub_prev_sst_uid',on_delete=models.DO_NOTHING)
sub_sst_uid = models.ForeignKey(SstSystemStatus, related_name='sub_sst_uid',on_delete=models.DO_NOTHING)
startdatetime = models.DateTimeField()
enddatetime = models.DateTimeField()
createdon = models.DateTimeField()
createdby = models.CharField(max_length=150)
createdfrom = models.CharField(max_length=150)
modifiedon = models.DateTimeField()
modifiedby = models.CharField(max_length=150)
modifiedfrom = models.CharField(max_length=150)
class Meta:
managed = False
db_table = 'sub_subscriber'
class SubSubscriber references foreign key sst_uid of table/class SstSystemStatus twice (previous and current status). It seems Django doesn't like it. Other tables such as VneVirtualNetwork (which contain a "single" foreign key references) don't cause any issue. The admin GUI allows me to display and change their data.
The fault message shows that Django tries to complement the name of field sub_prev_sst_uid with '_id'. If I comment the relevant line in file model.py and try to display the subscriber table it will cause the same error, this time with field sub_sst_uid. How can I prevent Django from appending '_id'?
Thanks in advance for any advice.
By default, Django will use the related name and/or the chosen class field name, add a suffix "_id" and try to locate a column of this name in the database. Unless you explicitly define the db_column as follows:
sub_sst_uid = models.ForeignKey('SstSystemStatus', db_column='sub_sst_uid', related_name='sub_sst_uid', on_delete=models.DO_NOTHING)
sub_prev_sst_uid = models.ForeignKey('SstSystemStatus', db_column='sub_prev_sst_uid', related_name='sub_prev_sst_uid', on_delete=models.DO_NOTHING)
Related
my models.py
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_registered = models.IntegerField(default=0)
# registered_students = models.ManyToManyField(RegisteredNames, null=True, blank=True)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass_id = models.ForeignKey
I am creating a endpoint where when a user register himself his name will get added to registered_students , so i had made a registered students ManyToMany Field hoping it will get updated when a user is registered but then i understand that it will contain all the names that are present in the RegisteredNames Model meaning names registered across all the liveclasses but i want only the names that are registered for a particular liveclass in the field so i need a array like field which i think is not possible so please help me in improving my logic, how can i achieve it
The documentation and django tutorials are very good: https://docs.djangoproject.com/en/3.2/topics/db/models/ https://docs.djangoproject.com/en/3.2/intro/tutorial02/#creating-models
Your code is very close. You don’t need the many-to-many field, and you need to specify the type of the Foreign key relationship in the RegisteredNames. You can do this:
class LiveClass_details(models.Model):
standard = models.ForeignKey(LiveClass, on_delete=models.CASCADE)
chapter_details = models.TextField(default='')
mentor_id = models.ForeignKey(Mentor, max_length=30, on_delete=models.CASCADE)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
doubtClass = models.OneToOneField(DoubtClasses, on_delete=models.PROTECT, null=True, blank=True)
isDraft = models.BooleanField(default=True)
ratings = models.FloatField(default=0)
no_of_students_attended = models.IntegerField(default=0)
class Meta:
verbose_name_plural = 'LiveClass_details'
class RegisteredNames(models.Model):
name = models.CharField(max_length=100, unique=True)
liveclass = models.ForeignKey(LiveClass_details, on_delete=Models.CASCADE)
Then, simply:
name = RegisteredNames.objects.create(name="Dhruv", liveclass_id=1)
To get all the registered names from a liveclass_details:
names = LiveClass_details.objects.get(id=1).registerednames_set.all()
num_reg = len(names)
I have been searching for LEFT JOIN of Django on Stackoverflow, however, most of solution are just too complicated.
My models:
class Voucher(models.Model):
code = models.CharField(unique=True, max_length=255)
delivery_type = models.CharField(max_length=255)
description = models.CharField(max_length=255, blank=True, null=True)
start_at = models.DateTimeField()
end_at = models.DateTimeField()
discount_type = models.CharField(max_length=255)
discount_amount = models.FloatField(blank=True, null=True)
class VoucherCustomer(models.Model):
voucher_code = models.OneToOneField(Voucher, models.DO_NOTHING, db_column='voucher_code', primary_key=True)
customer_id = models.IntegerField()
times_used = models.BigIntegerField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
This is what I tried:
from django.db.models.sql.datastructures import Join
#I thought this one is like
from VoucherCustomer left join Voucher
on VoucherCustomer.voucher_code = Voucher.code
j=Join(VoucherCustomer, 'voucher_code',
Voucher,"LEFT JOIN" ,'code', True)
j.objects.filter(voucher_code ='SAIGONS247').values('code', 'delivery_type', 'description', 'times_used').values
However, I got this result in the end:
AttributeError: 'str' object has no attribute 'get_joining_columns'
If you are having a ForeignKey or OneToOne Relationship, you can access the related object's attributes directly using double underscores.
j = VoucherCustomer.objects.filter(voucher_code__code ='SAIGONS247')
j.values('voucher_code__code', 'voucher_code__delivery_type', 'voucher_code__description', 'times_used')
I have 2 models each with foreign keys to 2 tables. I'm trying to join the 1st table to the 3rd.
Here are my models:
Model 1:
class AppBillingBil(models.Model):
id_bil = models.AutoField(primary_key=True)
idtrp_bil = models.ForeignKey(AppTradingPartnerTrp, models.DO_NOTHING, db_column='idtrp_bil', blank=True,
null=True)
idcst_bil = models.ForeignKey(AppCustomerCst, models.DO_NOTHING, db_column='idcst_bil')
idbtp_bil = models.ForeignKey(AppBillingTypeBtp, models.DO_NOTHING, db_column='idbtp_bil')
class Meta:
db_table = 'app_billing_bil'
ordering = ['id_bil']
Model 2:
class AppCustomerCst(models.Model):
id_cst = models.AutoField(primary_key=True)
is_active_cst = models.BooleanField()
name_cst = models.CharField(max_length=50, blank=True, null=True)
Model 2:
class AppTradingPartnerTrp(models.Model):
id_trp = models.AutoField(primary_key=True)
tpid_trp = models.CharField('TPID', max_length=50, blank=True, null=True)
name_trp = models.CharField('Name', max_length=50)
Final Model Needed:
class AppCustomerTpRel(models.Model):
id_rel = models.AutoField(primary_key=True)
idcst_rel = models.ForeignKey(AppCustomerCst, models.DO_NOTHING, db_column='idcst_rel')
idtrp_rel = models.ForeignKey(AppTradingPartnerTrp, models.DO_NOTHING, db_column='idtrp_rel')
cust_vendor_rel = models.CharField(max_length=50, blank=True, null=True)
I need to join on the following criteria:
idtrp_bil__id_trp = idtrp_rel
idcst_bil__id_cst = idcst_rel
And I need to be able to use the cust_vendor_rel field from AppCustomerTpRel in a filter query on AppBillingBil
After reading the docs here: https://docs.djangoproject.com/en/3.0/topics/db/queries/#spanning-multi-valued-relationships I tried this, and was successful:
idcst_bil__appcustomertprel__cust_vendor_rel
I realized I needed to include the target model name in the value grab.
I want to make a request from two tables at once, I registered dependencies in the class. But the request does not work for me. What is wrong with him?
views.py
def payments(request):
paymentsss = Transaction.objects.select_related("currency_id")[:5]
return render(request, "payments.html", {"paymentsss": paymentsss})
models.py
class Transaction(models.Model):
id = models.BigIntegerField(blank=True, null=False, primary_key=True)
currency_id = models.ForeignKey(Currency, null=True, on_delete=models.CASCADE)
deal_id = models.ForeignKey(Deal, null=True, related_name='deal', on_delete=models.CASCADE)
service_instance_id = models.ForeignKey(ServiceInstance, null=True, related_name='service_instance', on_delete=models.CASCADE)
payment_source_id = models.ForeignKey(PayerPaymentSource, null=True, related_name='payment_source', on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
amount = models.IntegerField(blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True)
context = models.TextField(blank=True, null=True) # This field type is a guess.
class Meta:
managed = False
db_table = '"processing"."transaction"'`enter code here`
And Currency for example:
class Currency(models.Model):
id = models.SmallIntegerField(blank=True, null=False, primary_key=True)
name = models.CharField(max_length=128, blank=True, null=True)
iso_name = models.CharField(max_length=3, blank=True, null=True)
minor_unit = models.SmallIntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = '"processing"."currency"'
My Error:
I would be glad if there is an example of how to make a larger request. From 3-4 tables.
Change the db_table
class Meta:
managed = False
db_table = 'processing.transaction'
class Meta:
managed = False
db_table = 'processing.currency'
You need to change the column names for the foreign keys: e.g. currency = ForeignKey(...) and deal = ForeignKey(...).
The field is a reference to the object itself, not to the id of the object. You can see that behind the scenes, Django queries using currency_id_id which doesn't make sense.
If your column name is currency_id (in your database), then your field name should be currency.
I'm working with a legay database so I have to set managed = False, which means I cannot update the database schema.
What I'm trying to do is select branches based on project id. Ideally in branches table it should have a project_id as foreign key but the previous system design is another table (branches_projects) stores this relationship.
I have been able to get around some problems using https://docs.djangoproject.com/en/1.11/topics/db/sql/#django.db.models.Manager.raw. raw() would return an RawQuerySet, which is not ideal.
I wonder if there's a way for me to define a foreign key in my branches table, which is the project_id, but refer/link that to the branches_projects table?
class Branches(models.Model):
name = models.CharField(max_length=128)
branchpoint_str = models.CharField(max_length=255)
dev_lead_id = models.IntegerField(blank=True, null=True)
source = models.CharField(max_length=255)
state = models.CharField(max_length=255)
kind = models.CharField(max_length=255)
desc = models.TextField(blank=True, null=True)
approved = models.IntegerField()
for_customer = models.IntegerField()
deactivated_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
codb_id = models.IntegerField(blank=True, null=True)
pm_lead_id = models.IntegerField(blank=True, null=True)
version = models.CharField(max_length=20, blank=True, null=True)
path_id = models.IntegerField(blank=True, null=True)
branchpoint_type = models.CharField(max_length=255, blank=True, null=True)
branchpoint_id = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'branches'
verbose_name_plural = 'Branches'
class Projects(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=40, primary_key=True)
status = models.CharField(max_length=255)
platform = models.CharField(max_length=255)
enabled = models.IntegerField()
path = models.CharField(max_length=128, blank=True, null=True)
tag_prefix = models.CharField(max_length=64, blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
codb_id = models.IntegerField(blank=True, null=True)
template = models.CharField(max_length=64, blank=True, null=True)
image_path = models.CharField(max_length=128, blank=True, null=True)
repository_id = models.IntegerField(blank=True, null=True)
number_scheme = models.CharField(max_length=32)
special_dir = models.CharField(max_length=32, blank=True, null=True)
project_family_id = models.IntegerField()
class Meta:
managed = False
db_table = 'projects'
verbose_name_plural = 'projects'
class BranchesProjects(models.Model):
# project_id = models.IntegerField()
# branch_id = models.IntegerField()
project = models.ForeignKey(Projects, on_delete=models.CASCADE)
branch = models.ForeignKey(Branches, on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'branches_projects'
My current raw query is like this
SELECT br.id, br.name, br.created_at, br.updated_at,
br.branchpoint_str, br.source
FROM branches as br
LEFT JOIN branches_projects as bp
ON br.id = bp.branch_id
WHERE bp.project_id = %s AND source != 'other'
ORDER BY updated_at DESC
I've finally got it working......
In the model, I use the manytomany as following:
class Branches(models.Model):
name = models.CharField(max_length=128)
project = models.ManyToManyField(Projects,
through='BranchesProjects',
related_name='project')
branchpoint_str = models.CharField(max_length=255)
Then to get the same result as my raw sql, i do the following:
def get_sb(project_id):
result = Branches.objects.filter(
project=Projects.objects.get(id=project_id).id,
).exclude(source='other').order_by('-updated_at')
print result.query
return result