Field missing in Django model? - python

Here is my model:
class SystemConfiguration(models.Model):
idSystemConfiguration = models.AutoField(primary_key=True)
mail_movement_subject = models.CharField(max_length=50, default="Movement Triggered")
mail_snapped_subject = models.CharField(max_length=50, default="Image Snapped")
mail_carbon_subject = models.CharField(max_length=50, default="Carbon Monoxide Triggered")
mail_door_subject = models.CharField(max_length=50, default="Door Activity Triggered")
door1_name = models.CharField(max_length=20, default="Garage Door")
door2_name = models.CharField(max_length=20, default="Garage Door 2")
door3_name = models.CharField(max_length=20, default="Garage Door 3")
metric = models.BooleanField()
mail_temp_subject = models.CharField(max_length=50, default="Temperature Triggered")
min_temp = models.DecimalField(decimal_places=1,max_digits=4)
max_temp = models.DecimalField(decimal_places=1,max_digits=4)
mail_humidity_subject = models.CharField(max_length=50, default="Humidity Triggered")
mail_to_user = models.CharField(max_length=50, default="")
min_humidity = models.DecimalField(decimal_places=1,max_digits=3)
max_humidity = models.DecimalField(decimal_places=1,max_digits=3)
def setDefaults(self):
print "Creating SystemConfig..."
self.mail_movement_subject = "Movement Triggered"
self.mail_snapped_subject = "Image Snapped"
self.mail_carbon_subject = "Carbon Monoxide Triggered"
self.mail_door_subject = "Door Activity Triggered"
self.door1_name = "Garage Door"
self.door2_name = "Garage Door 2"
self.door3_name = "Garage Door 3"
self.metric = False
self.mail_temp_subject = "Temperature Triggered"
self.min_temp = 28
self.max_temp = 100
self.mail_humidity_subject = "Humidity Triggered"
self.min_humidity = 40
self.max_humidity = 50
self.mail_to_user = ""
self.save()
def __str__(self):
return "SystemConfiguration:" + str(self.idSystemConfiguration) \
+ ",mail_movement_subject:" + str(self.mail_movement_subject) \
+ ",mail_snapped_subject:" + str(self.mail_snapped_subject) \
+ ",mail_carbon_subject:" + str(self.mail_carbon_subject) \
+ ",mail_door_subject:" + str(self.mail_door_subject) \
+ ",Door1Name:" + str(self.door1_name) \
+ ",Door2Name:" + str(self.door2_name) \
+ ",Door3Name:" + str(self.door3_name) \
+ ",Metric:" + str(self.metric) \
+ ",mail_temp_subject:" + str(self.mail_temp_subject) \
+ ",minTemp:" + str(self.min_temp) \
+ ",maxTemp:" + str(self.max_temp) \
+ ",mail_humidity_subject:" + str(self.mail_humidity_subject) \
+ ",minHumid:" + str(self.min_humidity) \
+ ",maxHumid:" + str(self.max_humidity) \
+ ",mail_to_user:" + str(self.mail_to_user) \
+ ",wan_port:" + str(self.wan_port) \
+ ",wan_video_port:" + str(self.wan_video_port) \
+ "\n"
Here is where I am trying to access it (note that I am running a script outside of django, and hence the sys.path.apend(...) and os.environ[...] shenanigans:
import sys
import os
sys.path.append(os.path.abspath("/home/pi/garageMonitor/django/garageMonitor"))
os.environ['DJANGO_SETTINGS_MODULE'] = 'garageMonitor.settings'
from garageMonitor.models import SystemConfiguration
def handleMailFile(file):
config = SystemConfiguration.objects.filter(idSystemConfiguration=1)
config = config[0]
for x in config.__dict__:
print x
print len(config.__dict__)
Here is the results of the run:
mail_snapped_subject
mail_humidity_subject
mail_carbon_subject
max_humidity
door2_name
max_temp
_state
idSystemConfiguration
min_humidity
mail_door_subject
min_temp
door3_name
mail_temp_subject
mail_movement_subject
metric
door1_name
16
Note that all of the fields except mail_to_user are printed in the for loop! I checked the database and sure enough, the mail_to_user field is there with the correct length and type.
Any suggestions would be most appreciated.
I tried adding another field identical to one that was actually working (changed the name.) Django created the field in the database, but it did not show up in the list of dict elements either?!?
I added another column in the database with django code and re-ran the setup. The coded added the column (with the default value), but still when I run the following:
import sys
import os
sys.path.append(os.path.abspath("/home/pi/garageMonitor/django/garageMonitor"))
os.environ['DJANGO_SETTINGS_MODULE'] = 'garageMonitor.settings'
from garageMonitor.models import SystemConfiguration
config = SystemConfiguration.objects.filter(idSystemConfiguration=1)
config = config[0]
for x in config.__dict__:
print x
print len(config.__dict__)
I only get 16 entries in the dict object and the new column is not there. I removed all .pyc files thinking there may be some artifact laying around, but that did not help either.
So, I tried another approach. I created a new model (Jordan) by copying the original one and added it to the models.py file. I ran the setup code. It created the table correctly in the database, but when I tried to access the model, I get the following error:
ImportError: cannot import name Jordan
Arrrgggghhhhh!!!!!
tried moving to another directory (django) and ran the following:
python...
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'garageMonitor.settings'
from garageMonitor.models import Jordan
config = Jordan.objects.filter(idSystemConfiguration=1)
config = config[0]
for x in config.__dict__:
print x
And here is my output:
_known_related_objects
_sticky_filter
_db
_result_cache
_prefetch_done
_for_write
query
model
_prefetch_related_lookups
_hints
(not remotely like what the database table looks like!)

Related

peewee - change schema dynamically

I have the same question/problem than this post -> peewee - modify db model meta (e.g. schema) dynamically . I want to change the schema field in my Meta class dynamically. This is my code:
class GPSPosition(Model):
def __init__(self, esquema, vehiculo, fechaFrom):
self.esquema = esquema + '_org'
self.vehiculo = vehiculo
self.fechaFrom = fechaFrom
orgid = BigIntegerField()
id = BigIntegerField()
vehicleid = BigIntegerField()
driverid = BigIntegerField()
originaldriverid = BigIntegerField(null=False)
blockseq = IntegerField(null=False)
time = DateTimeField(null=False)
latitude = FloatField(null=False)
longitude = FloatField(null=False)
altitude = SmallIntegerField(null=False)
heading = SmallIntegerField(null=False)
satellites = SmallIntegerField(null=False)
hdop = FloatField(null=False)#float
ageofreading = IntegerField(null=False)
distancesincereading = IntegerField(null=False)
velocity = FloatField(null=False)
isavl = BooleanField(null=False)
coordvalid = BooleanField(null=False)
speedkilometresperhour = DecimalField(null=False)
speedlimit = DecimalField(null=False)
vdop = SmallIntegerField(null=False)
pdop = SmallIntegerField(null=False)
odometerkilometres = DecimalField(null=False)
formattedaddress = CharField(null=False)
source = CharField(null=False)
class Meta:
database = db
schema = esquema
db_table = 'test_gpspositions'
primary_key = CompositeKey("orgid", "id")
Can someone please show me the light about this? Thanks!
Well I'll answer my own question since I found the answer time ago and it's very simple, just add this 1-2 lines at the point you want to change the schema name:
schemaname = 'your_schema_name'
setattr(YourPeeweeModel._meta, "schema", schemaname)
Works fine.

Casting result of an F function to an int

I have a simple Django application were I try to aggregate multiple values into an annotation for easier processing on the client side.
Basically, I need to sum the values of multiple columns into one.
For this I'm trying to use annotate with F functions:
qs = TimeReport.objects \
.filter(year=year, term=term) \
.annotate(
created_by_first_name=F('created_by__first_name'),
created_by_last_name=F('created_by__last_name'),
total_hours = F('master_thesis_supervision_hours')
+ F('semester_project_supervision_hours')
+ F('other_job_hours')
+ F('MAN_hours')
+ F('exam_proctoring_and_grading_hours')
+ F('class_teaching_exam_hours')
+ F('class_teaching_practical_work_hours')
+ F('class_teaching_preparation_hours')
+ F('class_teaching_teaching_hours'),
) \
.all().values()
Suprisingly, when I inspect the content of the calculated field, it does not contain anything:
list(qs)[0]['total_hours']
None
Trying to cast the result of the F function does not either:
...
total_hours = int(F('master_thesis_supervision_hours'))
+int(F('semester_project_supervision_hours'))
+ ...
I also tried to update the models.py to add a property:
#property
def total_hours(self):
return self.master_thesis_supervision_hours + self.class_teaching_total_hours + self.semester_project_supervision_hours + self.other_job_hours + self.MAN_hours + self.exam_proctoring_and_grading_hours
and update the views.py accordingly:
qs = TimeReport.objects \
.filter(year=year, term=term) \
.annotate(
created_by_first_name=F('created_by__first_name'),
created_by_last_name=F('created_by__last_name'),
total_hours = F('total_hours'),
) \
.all().values()
But I get the following error:
django.core.exceptions.FieldError: Cannot resolve keyword 'total_hours' into field.
What would be the correct way to do this?

invalid literal for int() with base 10: 'string name'

I am making an API module which saves weather data to my Django database by running a single Django management command, which retries all the data from a source API. I've created a model 'weather data' which has all the required datatypes. I've a management command written which directly saves data to my database.
The snippet of management command and models.py is shown below.
def handle(self,*args,**kwargs):
for city in input_file:
city_name = city.strip()
print(city_name)
full_api_url = api + city_name + '&mode=json&units=' + unit + '&APPID=' + user_api
full_wet_url = weather_api + city_name + '&mode=json&units=' + unit + '&APPID=' + user_api
try:
data = requests.get(full_api_url).json()
dta = requests.get(full_wet_url).json()
city_id = dta["id"]
longitude = dta["coord"]["lon"]
latitude= dta["coord"]["lat"]
for dt in data["list"]:
temp = dt["main"]["temp"]
temp_min = dt["main"]["temp_min"]
temp_max = dt["main"]["temp_max"]
pressure = dt["main"]["pressure"]
sea_level = dt["main"]["sea_level"]
grnd_level = dt["main"]["grnd_level"]
humidity = dt["main"]["humidity"]
weather = dt["weather"][0]
main = weather["main"]
description = weather["description"]
clouds = dt["clouds"]["all"]
wind_speed = dt["wind"]["speed"]
wind_deg = dt["wind"]["deg"]
dt_txt = dt["dt_txt"]
wd = weatherdata(city_name,city_id,latitude,longitude,dt_txt,temp,temp_min,temp_max,pressure,sea_level,grnd_level,humidity,main,description,clouds,wind_speed,wind_deg).save()
print ("Success")
except Exception as e:
print (e)
pass
class weatherdata(models.Model):
city_name = models.CharField(max_length = 80)
city_id = models.IntegerField(default=0)
latitude = models.FloatField(null=True , blank=True)
longitude = models.FloatField(null=True , blank=True)
dt_txt = models.DateTimeField()
temp = models.FloatField(null = False)
temp_min = models.FloatField(null = False)
temp_max = models.FloatField(null = False)
pressure = models.FloatField(null = False)
sea_level = models.FloatField(null = False)
grnd_level = models.FloatField(null = False)
humidity = models.FloatField(null = False)
main = models.CharField(max_length=200)
description = models.CharField(max_length=30)
clouds = models.IntegerField(null=False)
wind_speed = models.FloatField(null = False)
wind_degree = models.FloatField(null = False)
if I try executing 'python manage.py theweather'(the weather being the name of management command file), am getting an error stating:
nantapur
invalid literal for int() with base 10: 'Anantapur'
Chittoor
invalid literal for int() with base 10: 'Chittoor'
Kakinada
invalid literal for int() with base 10: 'Kakinada'
for all the city names in headquarters.csv file.
what is the solution for this error?
You should use named parameters, using positional ones is "unstable" since if you later add some field, then it might go wrong. Note that the first parameter is here the implicit primary key:
wd = weatherdata.objects.create(
city_name=city_name,
city_id=city_id,
latitude=latitude,
longitude=longitude,
dt_txt=dt_txt,
temp=temp,
temp_min=temp_min,
temp_max=temp_max,
pressure=pressure,
sea_level=sea_level,
grnd_level=grnd_level,
humidity=humidity,
main=main,
description=description,
clouds=clouds,
wind_speed=wind_speed,
wind_deg=wind_deg
)
That being said, I'm not sure the modeling is good here, it contains a lot of data duplication.
Note that class names are usually written in CamelCase, so it should be WeatherData, not weatherdata.

Can search for a record in a shapefile but how to get other fields

I can search a shapefile for an attribute and it works fine but I don't know how to get the other fields in that record once the correct records is found. Don't know if I should use SearchCursor or SelectLayerByAttribute_management.
townlands = r'F:\MyProject\Assignment\townlands.shp'
outpath = r'F:\MyProject\Assignment'
the_townland=str(text_search_townland.get())
selection = str(""" "NAME_TAG" = '""" + the_townland + "'")
selection2 = ????????????????
print selection, selection2
This code is working in that it finds the townland that the user puts in text_search_townland and it prints it as selection. I'm looking to get another field called OSM_USER from that record into selection2.
I got this working after lots of trial and error. It does need SearchCursor or at least that is how I got it working.
def new_record():
#set environment variables.
arcpy.env.workspace = r'F:\MyProject\Assignment\folklore.gdb'
myPath = r'F:\MyProject\Assignment\folklore.gdb'
editRows = arcpy.da.InsertCursor('folklore', '*')
print editRows.fields
# get the centroid of the townland from townland_centroid (fc) based on the
# townland the user enters.
database = r'F:\MyProject\Assignment\folklore.gdb'
fc = database + '/' + 'townland_centroid'
the_townland=str(text_search_townland.get())
fields = ['NAME_TAG', 'X_coord', 'Y_coord']
whereClause = '"NAME_TAG"' + " = '" + the_townland + "'"
with arcpy.da.SearchCursor(fc, fields, whereClause) as cursor:
for row in cursor:
print('{0}, {1}, {2}'.format(row[0], row[1], row[2]))
X_coord = str(row[1])
Y_coord = str(row[2])
del cursor
# Set variables with values that will populate 'folklore' featureclass.
OID = 1
ptShape = arcpy.Point(0,0)
townland = text_search_townland.get()
county = var_county2.get()
category = var_category.get()
URL = text_search_URL.get()
spec_location = "text_search_speclocation.get()"
date_entered = text_search_date_entered.get()
story_year = int(text_search_story_year.get())
X_coord_put = X_coord
Y_coord_put = Y_coord
newRecord = [OID, ptShape, townland, county, URL, spec_location, date_entered, story_year, category, X_coord, Y_coord]
editRows.insertRow(newRecord)
del editRows
Hope this helps someone.

Proper way to format date for Fedex API XML

I have a Django application where I am trying to make a call to Fedex's API to send out a shipping label for people wanting to send in a product for cash. When I try to make the call though it says there is a data validation issue with the Expiration field in the XML I am filling out. I swear this has worked in the past with me formatting the date as "YYYY-MM-DD", but now it is not. I read that with Fedex, you need to format the date as ISO, but that is also not passing the data validation. I am using a python package created to help with tapping Fedex's API.
Django view function for sending API Call
def Fedex(request, quote):
label_link = ''
expiration_date = datetime.datetime.now() + datetime.timedelta(days=10)
# formatted_date = "%s-%s-%s" % (expiration_date.year, expiration_date.month, expiration_date.day)
formatted_date = expiration_date.replace(microsecond=0).isoformat()
if quote.device_type != 'laptop':
box_length = 9
box_width = 12
box_height = 3
else:
box_length = 12
box_width = 14
box_height = 3
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
## Page 411 of FedEx Dev Guide - 20.14 Email Labels
CONFIG_OBJ = FedexConfig(key=settings.FEDEX_KEY, password=settings.FEDEX_PASSWORD, account_number=settings.FEDEX_ACCOUNT,
meter_number=settings.FEDEX_METER, use_test_server=settings.USE_FEDEX_TEST)
fxreq = FedexCreatePendingShipRequestEmail(CONFIG_OBJ, customer_transaction_id='xxxxxx id:01')
fxreq.RequestedShipment.ServiceType = 'FEDEX_GROUND'
fxreq.RequestedShipment.PackagingType = 'YOUR_PACKAGING'
fxreq.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
fxreq.RequestedShipment.ShipTimestamp = datetime.datetime.now()
# Special fields for the email label
fxreq.RequestedShipment.SpecialServicesRequested.SpecialServiceTypes = ('RETURN_SHIPMENT', 'PENDING_SHIPMENT')
fxreq.RequestedShipment.SpecialServicesRequested.PendingShipmentDetail.Type = 'EMAIL'
fxreq.RequestedShipment.SpecialServicesRequested.PendingShipmentDetail.ExpirationDate = formatted_date
email_address = fxreq.create_wsdl_object_of_type('EMailRecipient')
email_address.EmailAddress = quote.email
email_address.Role = 'SHIPMENT_COMPLETOR'
# RETURN SHIPMENT DETAIL
fxreq.RequestedShipment.SpecialServicesRequested.ReturnShipmentDetail.ReturnType = ('PENDING')
fxreq.RequestedShipment.SpecialServicesRequested.ReturnShipmentDetail.ReturnEMailDetail = fxreq.create_wsdl_object_of_type(
'ReturnEMailDetail')
fxreq.RequestedShipment.SpecialServicesRequested.ReturnShipmentDetail.ReturnEMailDetail.MerchantPhoneNumber = 'x-xxx-xxx-xxxx'
fxreq.RequestedShipment.SpecialServicesRequested.PendingShipmentDetail.EmailLabelDetail.Recipients = [email_address]
fxreq.RequestedShipment.SpecialServicesRequested.PendingShipmentDetail.EmailLabelDetail.Message = "Xxxxxx Xxxxxx"
fxreq.RequestedShipment.LabelSpecification = {'LabelFormatType': 'COMMON2D', 'ImageType': 'PDF'}
fxreq.RequestedShipment.Shipper.Contact.PersonName = quote.first_name + ' ' + quote.last_name
fxreq.RequestedShipment.Shipper.Contact.CompanyName = ""
fxreq.RequestedShipment.Shipper.Contact.PhoneNumber = quote.phone
fxreq.RequestedShipment.Shipper.Address.StreetLines.append(quote.address)
fxreq.RequestedShipment.Shipper.Address.City = quote.city
fxreq.RequestedShipment.Shipper.Address.StateOrProvinceCode = quote.state
fxreq.RequestedShipment.Shipper.Address.PostalCode = quote.zip
fxreq.RequestedShipment.Shipper.Address.CountryCode = settings.FEDEX_COUNTRY_CODE
fxreq.RequestedShipment.Recipient.Contact.PhoneNumber = settings.FEDEX_PHONE_NUMBER
fxreq.RequestedShipment.Recipient.Address.StreetLines = settings.FEDEX_STREET_LINES
fxreq.RequestedShipment.Recipient.Address.City = settings.FEDEX_CITY
fxreq.RequestedShipment.Recipient.Address.StateOrProvinceCode = settings.FEDEX_STATE_OR_PROVINCE_CODE
fxreq.RequestedShipment.Recipient.Address.PostalCode = settings.FEDEX_POSTAL_CODE
fxreq.RequestedShipment.Recipient.Address.CountryCode = settings.FEDEX_COUNTRY_CODE
fxreq.RequestedShipment.Recipient.AccountNumber = settings.FEDEX_ACCOUNT
fxreq.RequestedShipment.Recipient.Contact.PersonName = ''
fxreq.RequestedShipment.Recipient.Contact.CompanyName = 'Xxxxxx Xxxxxx'
fxreq.RequestedShipment.Recipient.Contact.EMailAddress = 'xxxxxx#xxxxxxxxx'
# Details of Person Who is Paying for the Shipping
fxreq.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = settings.FEDEX_ACCOUNT
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Contact.PersonName = 'Xxxxx Xxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Contact.CompanyName = 'Xxxxx Xxxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Contact.PhoneNumber = 'x-xxx-xxx-xxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Contact.EMailAddress = 'xxxxxxx#xxxxxxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.StreetLines = 'Xxxxx N. xXxxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.City = 'Xxxxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.StateOrProvinceCode = 'XX'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.PostalCode = 'xxxxx'
fxreq.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.CountryCode = 'US'
# Package Info
package1 = fxreq.create_wsdl_object_of_type('RequestedPackageLineItem')
package1.SequenceNumber = '1'
package1.Weight.Value = 1
package1.Weight.Units = "LB"
package1.Dimensions.Length = box_length
package1.Dimensions.Width = box_width
package1.Dimensions.Height = box_height
package1.Dimensions.Units = "IN"
package1.ItemDescription = 'Phone'
fxreq.RequestedShipment.RequestedPackageLineItems.append(package1)
fxreq.RequestedShipment.PackageCount = '1'
try:
fxreq.send_request()
label_link = str(fxreq.response.CompletedShipmentDetail.AccessDetail.AccessorDetails[0].EmailLabelUrl)
except Exception as exc:
print('Fedex Error')
print('===========')
print(exc)
print('==========')
return label_link
Error Log
Error:cvc-datatype-valid.1.2.1: \\'2017-11-3\\' is not a valid value for \\'date\\'.\\ncvc-type.3.1.3: The value \\'2017-11-3\\' of element \\'ns0:ExpirationDate\\' is not valid."\\n }\\n }' (Error code: -1)

Categories