django model instance could not get the field after save - django

Here is my code:
models.py
class TblUser(models.Model):
uid = models.IntegerField(primary_key=True, db_column='ID') # Field name made lowercase.
username = models.CharField(max_length=3072, db_column='UserName', blank=True) # Field name made lowercase.
password = models.CharField(max_length=3072, db_column='PassWord', blank=True) # Field name made lowercase.
datesstart = models.DateTimeField(null=True, db_column='datesStart', blank=True) # Field name made lowercase.
datesend = models.DateTimeField(null=True, db_column='datesEnd', blank=True) # Field name made lowercase.
num = models.IntegerField(null=True, db_column='Num', blank=True) # Field name made lowercase.
power = models.IntegerField(null=True, db_column='Power', blank=True) # Field name made lowercase.
email = models.CharField(max_length=12288, blank=True)
class Meta:
db_table = u'tbl_user'
def __unicode__(self):
return '%d--%s--%d'%(self.uid,self.username,self.power)
views.py
from app.models import TblUser
def appendUser(self,name,pwd):
#I add a new user,and the primary_key:uid is autoincrement in datebase
user = TblUser.objects.create(username=name,password=pwd)
print user.uid#None
When I call the appendUser(),it will insert a new record into datebase, and the user(TblUser's instance) only have two valid fields(username,password), the other is empty.
How can I get the user.uid because I want handle other things by using it?

You should use an AutoField not an IntegerField for the pk: https://docs.djangoproject.com/en/1.4/ref/models/fields/#autofield

You might want to read this post, different approach using ModelForm:
Get Primary Key after Saving a ModelForm in Django

Related

Facing issue to connect to SQLLITE table using raw sql

I'm trying to connect to SQLite table using a raw sql query but unsuccessfully.
Here is my model:
class CsqAgentReport(models.Model):
nodeid_sessionid_sequenceno = models.TextField(db_column='NodeID-SessionID-SequenceNo', blank=True, null=True) # Field name made lowercase. Field renamed to remove unsuitable characters.
callstarttime = models.TextField(db_column='CallStartTime', blank=True, null=True) # Field name made lowercase.
callendtime = models.TextField(db_column='CallEndTime', blank=True, null=True) # Field name made lowercase.
contactdisposition = models.IntegerField(db_column='ContactDisposition', blank=True, null=True) # Field name made lowercase.
originatordn_callingnumber_field = models.IntegerField(db_column='OriginatorDN(CallingNumber)', blank=True, null=True) # Field name made lowercase. Field renamed to remove unsuitable characters. Field renamed because it ended with '_'.
destinationdn = models.IntegerField(db_column='DestinationDN', blank=True, null=True) # Field name made lowercase.
callednumber = models.IntegerField(db_column='CalledNumber', blank=True, null=True) # Field name made lowercase.
pivotoriginatordn = models.TextField(db_column='PivotOriginatorDN', blank=True, null=True) # Field name made lowercase.
pivotcallednumber = models.TextField(db_column='PivotCalledNumber', blank=True, null=True) # Field name made lowercase.
csqnames = models.TextField(db_column='CSQNames', blank=True, null=True) # Field name made lowercase.
queuetime = models.TextField(db_column='QueueTime', blank=True, null=True) # Field name made lowercase.
agentname = models.TextField(db_column='AgentName', blank=True, null=True) # Field name made lowercase.
ringtime = models.TextField(db_column='RingTime', blank=True, null=True) # Field name made lowercase.
talktime = models.TextField(db_column='TalkTime', blank=True, null=True) # Field name made lowercase.
worktime = models.TextField(db_column='WorkTime', blank=True, null=True) # Field name made lowercase.
nomcsq = models.TextField(db_column='NomCSQ', blank=True, null=True) # Field name made lowercase.
idunique = models.IntegerField(db_column='IDUnique', blank=True, null=True) # Field name made lowercase.
originatordnhandeled = models.IntegerField(db_column='OriginatorDNHANDELED', blank=True, null=True) # Field name made lowercase.
originatordnnothandeled = models.IntegerField(db_column='OriginatorDNNOTHANDELED', blank=True, null=True) # Field name made lowercase.
outboundmissedcall = models.TextField(db_column='OutboundMISSEDcall', blank=True, null=True) # Field name made lowercase.
missedcallshandeledy_n = models.IntegerField(db_column='MISSEDCALLSHANDELEDY-N', blank=True, null=True) # Field name made lowercase. Field renamed to remove unsuitable characters.
class Meta:
managed = False
db_table = 'CSQ Agent Report'
Here is the view I created:
def csq_detail_view(request):
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM 'CsqAgentReport'")
obj = cursor.fetchone()
context = {
'object': obj
}
return render(request,"CSQ/detail.html",{context})
and here is the html:
{% extends 'base.html' %}
{% block content %}
<ul>
{% for var_nbr_app_repond in object %}
<li> {{var_nbr_app_repond}} </li>
{% endfor %}
{% endblock %}
The error message is the following :
Request Method: GET
Request URL: http://127.0.0.1:8000/CSQ_Detail/
Django Version: 3.0.5
Exception Type: OperationalError
Exception Value:
no such table: CsqAgentReport.
no such table: CsqAgentReport.
the error is self explanatory, did you create the database ? is there sqlite3 file in your project root folder ?
run those commands :
(venv) python manage.py makemigrations
to create a migration for your model, and
(venv) python manage.py migrate
to create associated table in your database.
Update
you've made a mistake, refer to https://docs.djangoproject.com/en/3.1/ref/models/options/#db-table on how to rename/override table name using db_table in Meta class. it should be:
class CsqAgentReport(models.Model):
[..]
class Meta:
managed = False
db_table = 'csq_agent_report' # HERE snake lower-cased strings
Update 2
since you've renamed db_table to csq_agent_report instead the default one CsqAgentReport you should update the sql statement to
cursor.execute("SELECT * FROM 'csq_agent_report'")
in return statement you don't need to wrap context in dictionary {..} because it's already.
change those 2 lines:
def csq_detail_view(request):
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM 'CsqAgentReport'") # HERE
obj = cursor.fetchone()
context = {
'object': obj
}
return render(request,"CSQ/detail.html",{context}) # HERE
to
def csq_detail_view(request):
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM 'csq_agent_report'") # HERE
obj = cursor.fetchone()
context = {
'object': obj
}
return render(request,"CSQ/detail.html", context) # HERE
Update 3
you have to change managed to True instead Flase
refer to https://docs.djangoproject.com/en/3.1/ref/models/options/#managed
class CsqAgentReport(models.Model):
[..]
class Meta:
managed = True # Here
db_table = 'csq_agent_report' # HERE snake lowercased strings
and don't forget to rerun migration commands.

Django - Legacy database tables - Querying 2 one to many tables

I am new to Django and would like some advice on how to query from 3 tables.
I have 3 tables from legacy database mapped in to models (Patient, PrescribedMeds, PrescribedMedsSchedule). We can't change this structure since this will have to remain active while we create the Django application.
1 patient can have many prescribed medication.
1 prescribed medication can have several times in the schedule
Below is the model in django.
models.py
class Patient(models.Model):
patient_name = models.CharField(db_column='patient_name', max_length=50)
dob = models.DateTimeField(db_column='DOB', blank=True, null=True) # Field name made lowercase.
gender = models.CharField(db_column='Gender', max_length=7) # Field name made lowercase.
dateofentry = models.DateTimeField(db_column='DateOfEntry', blank=True, null=True) # Field name made lowercase.
....
....
class Meta:
managed = False
db_table = 'patient'
def __str__(self):
return self.patient_name
class PrescribedMeds(models.Model):
#id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
patient_id= models.ForeignKey(Patient, models.DO_NOTHING, db_column='patient_id')
med_type = models.SmallIntegerField(db_column='Type') # Field name made lowercase.
name_of_medication = models.CharField(db_column='Name_Of_Medication', max_length=50, blank=True, null=True) # Field name made lowercase.
rxno = models.CharField(db_column='RxNo', max_length=50, blank=True, null=True) # Field name made lowercase.
date_filled = models.DateTimeField(db_column='DateFilled', blank=True, null=True) # Field name made lowercase.
....
....
class Meta:
managed = False
db_table = 'prescribed_meds'
def __str__(self):
return str(self.id) + ", " + self.name_of_medication + ", " + str(self.childno)
class PrescribedMedsSchedule(models.Model):
#id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
prescribed_meds_id = models.ForeignKey(PrescribedMeds, models.DO_NOTHING, db_column='prescribed_meds_ID') # Field name made lowercase.
medication_date = models.DateField()
medication_time = models.DateTimeField()
quantity = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
form = models.CharField(max_length=1, blank=True, null=True)
class Meta:
managed = False
db_table = 'prescribed_meds_schedule'
I am trying to get the right syntax in Django to display data from the 3 columns (Prescribed_Meds.ID, PrescribedMeds.name_of_medication, Patient.patient_name, PrescribedMedsSchedule.medication_date, PrescribedMedsSchedule.medication_time).
In SQL the query would be
SELECT prescribed_meds.ID, prescribed_meds.Name_Of_Medication, patient.patient_name, prescribed_meds_schedule.medication_date, prescribed_meds_schedule.medication_time
FROM prescribed_meds_schedule
INNER JOIN (prescribed_meds INNER JOIN patient ON prescribed_meds.patient_id = patient.id) ON prescribed_meds_schedule.prescribed_meds_ID = prescribed_meds.ID;
What would be the correct query in Django? I am having an issue since there is no relationship from PrescribedMedsSchedule to Patient table.
I have tried the following:
my_obj = PrescribedMedsSchedule.objects.all().selected_related(
'prescribed_meds_id'
).prefetch_related('PrescribedMeds__patient_id')
However, this query does not bring up the Patient table/model.
Any advice would be appreciated.
It's worth starting with a note on what django does internally with a FK. You have a suffix in your models of _id but django will do this to the database column automatically. So in your model you could have an easier to read field, patient = models.ForeignKey(Patient) and it will be patient_id in the database.
select_related follows foreign-key relationships, so you're right to do that. If you want to INNER join you should follow the foreign-keys. In your case use the
double-underscore to get through the models:
PrescribedMedsSchedule.objects.all().select_related(
'prescribed_meds_id'
).select_related('prescribed_meds_id__patient_id')
Or you could use 2 queries and use the id values from PrescribedMeds to then query PrescribedMedsSchedule. That would be something like;
meds = PrescribedMeds.objects.all().select_related('patient_id')
med_ids = meds.values_list('id', flat=True)
schedules = PrescribedMedsSchedule.objects.filter(prescribed_meds_id__in=med_ids)

Django Join on Composite foreign key

I have a relationship as Follows
class Tblrfqvendor(models.Model):
"""RFQ Master for Vendors
This typical represents the same RFQ sent to different people
"""
ven_rfqid = models.ForeignKey(Tblrfqitem, db_column='RFQID', on_delete=models.DO_NOTHING, primary_key=True,related_name="venrfq") # Field name made lowercase.
lineitem = models.IntegerField(db_column='LineItem') # Field name made lowercase.
vendorid = models.CharField(db_column='VendorID', max_length=10) # Field name made lowercase.
class Meta:
managed = False
db_table = 'tblRFQVendor'
constraints = [constraints.UniqueConstraint(fields=['ven_rfqid', 'lineitem', 'vendorid'], name='unique_vendor_rfq')]
ordering = ['-lastrevdate']
class Tblrfqitem(models.Model):
"""A Line Item for a particular Master Vendor RFQ
"""
item_rfqid = models.ForeignKey(Tblrfqmaster, db_column='RFQID', on_delete=models.DO_NOTHING, primary_key=True,related_name='items') # Field name made lowercase.
lineitem = models.IntegerField(db_column='LineItem')
itemid = models.CharField(db_column='ItemID', max_length=100, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'tblRFQItem'
constraints = [constraints.UniqueConstraint(fields=['item_rfqid','lineitem'], name='unique_item')]
How can I get it so that I can serialize on both lineitem and ven_rfid instead of just the single primary key?

Django join different tables

This is what i got in the models
class SFE(models.Model):
snpid = models.ForeignKey(Snps, models.DO_NOTHING, db_column='SNPID', primary_key=True) # Field name made lowercase.
elementid = models.ForeignKey(Functionalelement, models.DO_NOTHING, db_column='ElementID') # Field name made lowercase.
celllineid = models.ForeignKey(Celllines, models.DO_NOTHING, db_column='CELLLINEID') # Field name made lowercase.
countexperiments = models.PositiveIntegerField(db_column='countExperiments') # Field name made lowercase.
filetype = models.CharField(db_column='fileType', max_length=10) # Field name made lowercase.
class Meta:
managed = False
db_table = 'SNPs_FunctionalElement'
unique_together = (('snpid', 'elementid', 'celllineid', 'filetype'),)
def __str__(self):
return str(str(self.snpid) + str(self.elementid) + str(self.celllineid) + str(self.filetype))
class Functionalelement(models.Model):
elementid = models.AutoField(db_column='ElementID', primary_key=True) # Field name made lowercase.
name = models.CharField(unique=True, max_length=55)
class Meta:
managed = False
db_table = 'FunctionalElement'
def __str__(self):
return str(self.elementid)
class Snps(models.Model):
snpid = models.AutoField(db_column='SNPID', primary_key=True) # Field name made lowercase.
rsid = models.CharField(unique=True, max_length=20)
chrom = models.CharField(max_length=5)
pos = models.PositiveIntegerField()
ref = models.CharField(max_length=1)
alt = models.CharField(max_length=1)
maf1000genomes = models.FloatField(blank=True, null=True)
maftopmed = models.FloatField(db_column='mafTOPMed', blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'SNPs'
def __str__(self):
return str(self.snpid)
Now i want to join FunctionalElement with SFE in order to retrieve the field FunctionalElement.name given a specific SFE.snpid.
I tried with SFE.objects.select_related('elementid__name') but i know it's wrong and i can't understand how to work with django ORM
To get a simple object you need to do: a = SFE.objects.get(snpid=THE_SPECIFICSNPID) later you can access to all the related objects, for example: a.elementid.name will return what you want.
The Django ORM take retrieve the object for you, that is because "lazzy loading". That means that if you need a related object later Django will get it for you, of course, it need to do another query and to avoid that you need to call the method select_related
Summarizing:
To get the name you can do:
name = SFE.objects.get(snpid=THE_SPECIFICSNPID).select_related('elementid').elementid.name
It should works

ManyToMany model error

I have a Cruise offer class related to a model called SpecialInterest. I now realize that I have the same exact thing going on in my LandOffer model (elsewhere). So I want to get rid of the cruise.SpecialInterest and replace it with the land.SpecialInterest.
This is my error:
Error: One or more models did not validate:
cruise.cruiseoffer: 'special_interest' has an m2m relation with model land.models.SpecialInterest, which has either not been installed or is abstract.
I dropped the CruiseOffer table, but when I syncdb I fail.
Help?
class CruiseOffer(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=300) # Field name made lowercase.
name_enca = models.CharField(max_length=300, blank=True) # Field name made lowercase.
name_frca = models.CharField(max_length=300, blank=True) # Field name made lowercase.
supplier = models.ForeignKey('CruiseSupplier')
#special_interest = models.ManyToManyField('SpecialInterest')
special_interest = models.ManyToManyField('land.models.SpecialInterest')
def __unicode__(self):
return "%6d %s" % (self.id, self.name,)
Right syntax is:
from land.models import SpecialInterest
...
class Crui...
...
special_interest = models.ManyToManyField(SpecialInterest)