I am developing a django app where I use a legacy database. This database doesn't have primary key or constraint in any table. This are two of my models
class Provider(models.Model):
id_provider = models.IntegerField(blank=True, null=True, primary_key=True)
name = models.CharField(max_length=50, blank=True)
type = models.CharField(max_length=10, blank=True)
signed = models.CharField(max_length=15, blank=True)
currency = models.CharField(max_length=1, blank=True)
class Meta:
managed = False
db_table = 'mpc_proveedores'
class Master(models.Model):
id_provider = models.ForeignKey(Proveedor)
anio = models.IntegerField(blank=True, null=True)
mes = models.IntegerField(blank=True, null=True)
nombre_prov = models.CharField(max_length=50, blank=True)
tipo_conci = models.CharField(max_length=30, blank=True)
f_recepcion = models.DateField(blank=True, null=True)
e_recepcion = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'mpc_master'
I need to show a table based on the model Master and I need to display the name of the provider instead of the id_provider.
This is my view
def monitorViewV2(request):
table = MonitorTable(Master.objects.all())
RequestConfig(request).configure(table)
return render(request,'monitorv2.html',{'table': table})
When I try to see the template in the browser, the next error is showed
ORA-00904: "MPC_MASTER"."ID_PROVIDER_ID": invalid identifier
I don't know if the error is because I don't have relationships in the database or if I need to create a function in the view to display the name instead of the id_provider.
Can you bring me some snippet or link where I can take some ideas to resolve this issue
Thanks in advance
Django needs there to be an integer DB column for foreign key relations, which will hold the PK of the related object. It looks like that column is id_provider in this case, so you should specify that in your field declaration. I'd also use a different field name to avoid confusion:
provider = models.ForeignKey(Proveedor, db_column='id_provider')
The docs provide a little more context:
https://docs.djangoproject.com/en/1.7/ref/models/fields/#database-representation
Related
I have a set of tables that Ive turned into django models. The tables weren't architected very well and i can't change them, and it is causing problems for this one many to many relationship I'm trying to set up in my code.
Models
class Owner(models.Model):
owner_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True) # Field name made lowercase.
email = models.TextField(max_length=200, unique=True)
is_active = models.BooleanField( blank=True, null=True) # Field name made lowercase.
owned_apps_whistic = models.ManyToManyField("Applications", through="ApplicationOwnerXRef", related_name="owners_whistic")
#owned_apps_group = models.ManyToManyField("Applications", through="BusinessUnitOwnerXref", related_name="owners_group")
class Applications(models.Model):
application_id = models.UUIDField(primary_key=True)
url = models.TextField(blank=True, null=True)
name = models.TextField(blank=True, null=True)
service = models.TextField(blank=True, null=True)
status = models.TextField(blank=True, null=True)
created_date = models.TextField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
business_unit_name = models.TextField(blank=True, null=True)
class BusinessUnitOwnerXref(models.Model):
id = models.AutoField(primary_key=True)
owner_uuid = models.ForeignKey(ApplicationOwner, models.DO_NOTHING, to_field="owner_uuid", db_column = "owner_uuid")
business_unit_name = models.TextField(max_length=100, null=True)
Owners can own applications by owning the group that owns the application, indicated in the BusinessUnitOwnerXref table.
The Application table and the BusinessUnitOwnerXref both have the business_unit_name column , and can be directly joined
I cant use a foreign key because the BusinessUnitOwnerXref.business_unit_name column isn't unique.
TLDR, Is there a way to create the many-to-many relationship between Applications and Owners, through BusinessUnitOwnerXref, without altering the existing tables or letting django create another table?
I have used the queryset before though this is my first attempt to JOIN tables but it's not working so far.
I am using django 3.2 and python 3.8.1
my models.py
class Mainjoinbook(models.Model):
fullsitename = models.TextField(primary_key=True)
creationdate = models.DateTimeField()
entrytypeid = models.BigIntegerField(blank=True, null=True)
title = models.TextField(blank=True, null=True)
tickettype = models.TextField(blank=True, null=True)
ticket = models.TextField(blank=True, null=True)
status = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'mainlogbook'
class Sitelocation(models.Model):
site_name = models.TextField(primary_key=True)
latitude = models.TextField(blank=True, null=True)
longitude = models.TextField(blank=True, null=True)
sites = models.ForeignKey(Mainjoinbook, on_delete=models.DO_NOTHING)
class Meta:
managed = False
db_table = 'tblsiteaccess'
I am trying to get all values from both tables joined in my views.py
qrylocations = Sitelocation.objects.select_related('sites').filter(sites__status='OPEN')
this results in this error as that column is created by django but doesn't belong to the table. I still can't workout how to resolve this as I have tried many options but always get in some kind of error and I hope someone can help me to see what I'm doing wrong in joining the tables on the primary keys defined
psycopg2.errors.UndefinedColumn: column tblsiteaccess.sites_id does not exist
the SQL output shown is as below.
output from qrylocations.query
SELECT "tblsiteaccess"."site_name", "tblsiteaccess"."latitude", "tblsiteaccess"."longitude", "tblsiteaccess"."sites_id", "mainlogbook"."fullsitename", "mainlogbook"."log_id", "mainlogbook"."creationdate", "mainlogbook"."entrytypeid", "mainlogbook"."title", "mainlogbook"."tickettype", "mainlogbook"."ticket", "mainlogbook"."status" FROM "tblsiteaccess" INNER JOIN "mainlogbook" ON ("tblsiteaccess"."sites_id" = "mainlogbook"."fullsitename") WHERE "mainlogbook"."status" = OPEN
A ForeignKey naturally needs a column in the database table. Since site_name itself is the primary key you should use that as a ForeignKey here, infact instead of a ForeignKey this needs to be a OneToOneField [Django docs] since it is also a primary key and needs to be unique:
class Sitelocation(models.Model):
site_name = models.OneToOneField(
Mainjoinbook,
on_delete=models.CASCADE,
primary_key=True,
db_column='site_name'
)
latitude = models.TextField(blank=True, null=True)
longitude = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'tblsiteaccess'
I had a same problem. db_column option is helpful.
In this case...
class Sitelocation(models.Model):
site_name = models.TextField(primary_key=True)
latitude = models.TextField(blank=True, null=True)
longitude = models.TextField(blank=True, null=True)
sites = models.ForeignKey(Mainjoinbook,
on_delete=models.DO_NOTHING,
db_column="sites"
)
class Meta:
managed = False
db_table = 'tblsiteaccess'
Good Afternoon,
I have a pair of models like the below:
class DeviceCircuitSubnets(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
circuit = models.ForeignKey(Circuit, on_delete=models.CASCADE, blank=True, null=True)
subnet = models.ForeignKey(Subnet, on_delete=models.CASCADE)
...
class BGPData(models.Model):
device_circuit_subnet = models.OneToOneField(DeviceCircuitSubnets, verbose_name="Device", on_delete=models.CASCADE)
bgp_peer_as = models.CharField(max_length=20, verbose_name='BGP Peer AS', blank=True, null=True)
bgp_session = models.CharField(max_length=10, verbose_name='BGP Session', blank=True, null=True)
bgp_routes = models.CharField(max_length=10, verbose_name='BGP Routes Received', blank=True, null=True)
service_status = models.CharField(max_length=10, verbose_name='Service Status', blank=True, null=True)
timestamp = models.DateTimeField(auto_now=True, blank=True, null=True)
I am filtering the DeviceCircuitSubnets and then I also want to access the BGPData related model via each filtered item.
service_data = DeviceCircuitSubnets.objects.filter(monitored=True, device__site_id=site_id) \
.select_related('device','circuit','subnet')
I have tried adding bgpdata to the select related and to prefetch but neither are currently working, I am returned with an error stating the model doesn't exist.
how would my query need to look to obtain each one to one field in a query set?
Thank you
Since you didn't set related_name attribute on OneToOneField, you need to use lower-cased model name for reverse relation:
service_data = DeviceCircuitSubnets.objects.filter(monitored=True, device__site_id=site_id) \
.select_related('bgpdata')
Note also that:
A DoesNotExist exception is raised when accessing the reverse relationship if an entry in the related table doesn’t exist
I've trying to setup a model to be populated with a csv file, and to use one of the fields as a foreignkey:
First, I tried creating a model from an existing postgresql table using inspectdb, migrating and then change the type of the field I want to relate from charfield to foreignkey, but I got errors
Then I tried creating an empty model with the inspectdb description, then importing a csv in postgresql, and finally changing the field i want to foreignkey. In the admin site I can view the imported data and the relations, but when I query the model I got another error with the foreignkey field, and it wont let me migrate (cant recognize the charfield, it asks for integer)
-the csv column I want for a foreignkey is charfield, when i create the model before importing the csv i got an error, then checking the datatype in the postgres table is says integer, can it be set to charfield??
What workflow work best for importing a csv to a model and use one of the fields as a foreignkey (charfield type)??
Thanks
This is the model to be related to :
class D_Roles(models.Model):
predio = models.CharField(max_length=254)
dest = models.CharField(max_length=254)
dir = models.CharField(max_length=254)
rol = models.CharField(max_length=254)
vlr_tot = models.FloatField()
ub_x2 = models.FloatField()
ub_y2 = models.FloatField()
instrum = models.CharField(max_length=254)
codzona = models.CharField(max_length=254)
nomzona = models.CharField(max_length=254)
geom = models.MultiPointField(srid=32719)
def __str__(self):
return self.rol
class Meta():
verbose_name_plural = "Roles SII"
The models I want to populate with csv:
class Dom2015CertInf(models.Model):
id = models.CharField(primary_key=True, max_length=80)
nombre_archivo = models.CharField(max_length=180, blank=True, null=True)
derechos = models.CharField(max_length=120, blank=True, null=True)
dir_calle = models.CharField(max_length=120, blank=True, null=True)
dir_numero = models.CharField(max_length=120, blank=True, null=True)
fecha_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_certificado = models.CharField(max_length=50, blank=True, null=True)
numero_solicitud = models.CharField(max_length=50, blank=True, null=True)
#Original field from inspectdb
#rol_sii = models.CharField(max_length=50, blank=True, null=True)
#FOREIGNKEY Changed after creating the model and importing the csv
rol_sii = models.ForeignKey(D_Roles, db_column='rol_sii', on_delete=models.CASCADE, default=0)
zona_prc = models.CharField(max_length=120, blank=True, null=True)
def __str__(self):
return str(self.numero_certificado)
class Meta:
managed = True
verbose_name_plural = "2015 Certificados Informaciones Previas"
ordering = ['numero_certificado']
I made some basic models for a listing of a business, like so:
class Business(models.Models):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=225, blank=True)
address = models.CharField(max_length=150, blank=True)
city = models.CharField(max_length=150, blank=True)
state_id = models.IntegerField(null=True, blank=True)
zip = models.CharField(max_length=33, blank=True)
country = models.CharField(max_length=150, blank=True)
url = models.CharField(max_length=765, blank=True)
class States(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=96)
state_abbr = models.CharField(max_length=24, blank=True)
In the admin when I edit each business it shows the state_id field. But how do I connect it with the state model to show a select dropdown listing of the states?
Also, how do I show the state abbreviation in the view of a business?
An alternative that doesn't require a separate state table:
from django.contrib.localflavor.us.us_states import STATE_CHOICES
class Business(models.Models):
...
state = models.CharField(max_length=2, choices=STATE_CHOICES, null=True, blank=True)
...
Edit in 2015 (django 1.8)
you should check the django official localflavor repo: https://github.com/django/django-localflavor.
from localflavor.us.models import USStateField
class Business(models.Models):
…
state = USStateField(null=True, blank=True)
…
Some tests are available on the repo for this specific usage.
Docs available here.
You need to use a ForeignKey field.
Make the following changes.
class Business(models.Models):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=225, blank=True)
address = models.CharField(max_length=150, blank=True)
city = models.CharField(max_length=150, blank=True)
#state_id = models.IntegerField(null=True, blank=True)
# Define a new state field that creates a ForeignKey relationship with States
state = models.ForeignKey('States', null=True, blank=True)
zip = models.CharField(max_length=33, blank=True)
country = models.CharField(max_length=150, blank=True)
url = models.CharField(max_length=765, blank=True)
class States(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=96)
state_abbr = models.CharField(max_length=24, blank=True)
#Define the __unicode__ method, which is used by related models by default.
def __unicode__(self):
return self.state_abbr
By default ForeignKey fields append '_id' to the field name when creating the column name in the database. So, the new "state" field in the Business class will automatically use the column "state_id" that you've previously defined, unless you've changed some of the default behavior of Django.
For more on this:
Check out Django's documentation of
the ForeignKey field
Search "ForeignKey" on stackoverflow.com