Django - populate model with foreignkey via csv import? - django

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']

Related

Django query fails with _id that is not used or created or referenced to

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'

Django: Update model with new foreign_key

I created a form with the model form manager. Before saving my TransactionProfile ModelForm, I want to connect it with an order model. When I print session_order_id it is the correct id, however self.order_set.get is always empty when I print it in the console. Anyone can help me with that? Would you in general solve it the way I did it here, or ist there a more clean method?
In my views.py I have the following:
t = transaction_profile.save(commit=False)
t.update_order_with_transaction_profile(session_order_id)
t.save()
transactions/models.py
class TransactionProfile(models.Model):
email = models.EmailField()
address_line_1 = models.CharField(max_length=120)
address_line_2 = models.CharField(max_length=120, null=True, blank=True)
city = models.CharField(max_length=120)
country = models.CharField(max_length=120)
state = models.CharField(max_length=120)
postal_code = models.CharField(max_length=120)
update = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
customer_id = models.CharField(max_length=120, null=True, blank=True)
def update_order_with_transaction_profile(self, session_order_id):
# In ModelManager or just in class TransactionProfile
o = self.order_set.get(order_id=session_order_id)
o.transaction_profile = self
o.save()
orders/models.py
class Order(models.Model):
order_id = models.CharField(max_length=10, unique=True)
customer_key = models.CharField(max_length=10, unique=True)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
transaction_profile = models.ForeignKey(TransactionProfile, blank=True, null=True, on_delete=models.CASCADE)
You need to save object to DB before using it as foreign key. Since in your code t is not saved in DB, update_order_with_transaction_profile will not work.
Instead of self.order_set, which gives you only orders related to specific profile(empty list for new object), you can directly query on Order model, note you need to save transaction_profile firts:
t = transaction_profile.save()
t.update_order_with_transaction_profile(session_order_id)
def update_order_with_transaction_profile(self, session_order_id):
# In ModelManager or just in class TransactionProfile
o = Order.objects.get(order_id=session_order_id)
o.transaction_profile = self
o.save()

Django migrations Many2Many Through model, ValueError: Cannot alter field

Hey guys I want to sort my many to many field and in that case I want to through. My code look something like this:
class SkirunRatePoint(models.Model):
latitude = models.DecimalField(u'lat', max_digits=10, decimal_places=6)
longitude = models.DecimalField(u'lng', max_digits=10, decimal_places=6)
elevation = models.DecimalField(max_digits=10, decimal_places=6, blank=True, null=True)
name = models.CharField(u'Name', max_length=200, blank=True, null=True)
class Meta:
verbose_name = u'Point'
verbose_name_plural = u'Points'
def __unicode__(self):
return unicode('{0} / {1}'.format(self.latitude, self.longitude))
class SkirunRoute(models.Model):
skirun = models.ForeignKey(Skirun, verbose_name=u'Path')
ratepoints = models.ManyToManyField(
SkirunRatePoint,
through="SkirunRatePointThrough",
verbose_name=u'Points',
blank=True,
)
class Meta:
verbose_name_plural = u'trasy z punktami'
def __unicode__(self):
return unicode(self.skirun)
class SkirunRatePointThrough(models.Model):
skirunroute = models.ForeignKey(SkirunRoute, related_name="skirun_route")
skirunratepoint = models.ForeignKey(SkirunRatePoint, related_name="skirun_rate_points")
order = models.IntegerField(
blank=True,
null=True,
)
Don't mind about indents, they are find on my pc.
Makemigrations is going fine, but when I try to migrate it throws me an error which says:
ValueError: Cannot alter field skirun.SkirunRoute.ratepoints into skirun.SkirunRoute.ratepoints - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)
Any ideas what might be the problem ?

Foreign key relationship error in django

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

Django 2.1 ProgrammingError at /admin column + _id does not exist

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)