Multiple try except in a serializer Django - django

I have a Warehouse model like the following:
class ShelfBin(models.Model):
bin_id = models.IntegerField(default=0)
bin_name = models.CharField(max_length=50, default=0)
class UnitShelf(models.Model):
shelf_id = models.IntegerField(default=0)
shelf_name = models.CharField(max_length=50, default=0)
bin = models.ManyToManyField(ShelfBin, blank=True)
class AisleUnit(models.Model):
unit_id = models.IntegerField(default=0)
unit_name = models.CharField(max_length=50, default=0)
shelf = models.ManyToManyField(UnitShelf, blank=True)
class ZoneAisle(models.Model):
aisle_id = models.IntegerField(default=0)
aisle_name = models.CharField(max_length=50, default=0)
unit = models.ManyToManyField(AisleUnit, blank=True)
class WarehouseZone(models.Model):
zone_id = models.IntegerField(default=0)
zone_name = models.CharField(max_length=50, default=0)
aisle = models.ManyToManyField(ZoneAisle, blank=True)
class Warehouse(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=250, default=0)
address = models.CharField(max_length=500, default=0)
zones = models.ManyToManyField(WarehouseZone, blank=True)
for this I have created a serializer like the following:
class WarehouseSerializer(serializers.ModelSerializer):
zones = WarehouseZonesSerializer(many=True)
class Meta:
model = Warehouse
fields = "__all__"
def create(self, validated_data):
print("validated data warehouse", validated_data)
zone_objects = validated_data.pop('zones', None)
instance = Warehouse.objects.create(**validated_data)
for item in zone_objects:
aisle_objects = item.pop('aisle')
wz_obj = WarehouseZone.objects.create(**item)
for data in aisle_objects:
unit_objects = data.pop('unit')
za_obj = ZoneAisle.objects.create(**data)
for u_data in unit_objects:
shelf_objects = u_data.pop('shelf')
au_obj = AisleUnit.objects.create(**u_data)
for s_data in shelf_objects:
bin_objects = s_data.pop('bin')
us_obj = UnitShelf.objects.create(**s_data)
for b_data in bin_objects:
b_obj = ShelfBin.objects.create(**b_data)
us_obj.bin.add(b_obj)
au_obj.shelf.add(us_obj)
za_obj.unit.add(au_obj)
wz_obj.aisle.add(za_obj)
instance.zones.add(wz_obj)
return instance
Now the problem is that sometimes warehouse can have zone, aisle, units, etc(all 5 sub-levels) but sometimes it can only be 1,2 or 0 level deep
and in that cases it raises error like this :
aisle_objects = item.pop('aisle')
KeyError: 'aisle'
So do I have to use try and except at each level of the loop or is there a better way to handle these exceptions?

Related

How to get recent values in this db?

I use sqlite.
class Member(models.Model):
member_id = models.AutoField(primary_key=True)
is_update = models.IntegerField(default=0)
member_name = models.CharField(max_length=50)
member_group = models.IntegerField(default=0)
room_name = models.CharField(max_length=20)
bed_name = models.CharField(max_length=20)
gender = models.IntegerField(default=0)
birth_date = models.DateField()
phone_number = models.CharField(max_length=11)
protector = models.CharField(default='protector',max_length=50)
def __str__(self):
return str(self.member_id)
def initIsUpdate(self):
self.is_update = 0
return 0
class Inpatient(models.Model):
member_id = models.ForeignKey(Member, on_delete=models.CASCADE, db_column = 'member_id', related_name='member')
inpatient_status = models.IntegerField(default=0)
is_in_room = models.IntegerField(default=0)
is_on_bed = models.IntegerField(default=0)
heart_rate = models.IntegerField(default=0)
breath_rate = models.IntegerField(default=0)
update_time = models.DateTimeField(auto_now_add=True, blank=True)
protector_name = models.CharField(max_length=50)
def __str__(self):
return str(self.member_id)
And Members are 4 people..
Each Members have same values in Inpatient DB.
It gets new queryset for every 1 sec.
And I want get 4 Member's most recent Inpatient DB.
How I get that DB??
class Inpatient(models.Model):
member_id = models.ForeignKey(Member, on_delete=models.CASCADE, db_column = 'member_id', related_name='member')
inpatient_status = models.IntegerField(default=0)
is_in_room = models.IntegerField(default=0)
is_on_bed = models.IntegerField(default=0)
heart_rate = models.IntegerField(default=0)
breath_rate = models.IntegerField(default=0)
update_time = models.DateTimeField(auto_now_add=True, blank=True)
protector_name = models.CharField(max_length=50)
class Meta:
get_latest_by = "update_time"
def __str__(self):
return str(self.member_id)
Now when you filter the members in views.py it will provide recent values..

How to aggregate on a foreign key and a specific field at the same time?

My table named Value has a one to many relationship with the table Country and the table Output_outcome_impact. I have a query that is working fine and gets what I want but then I need to do an average of the value field, but this average needs to be done for each unique id_output_outcome_impact and not the whole query.
class Country(models.Model):
country_name = models.CharField(max_length=255, primary_key=True)
CONTINENTCHOICE = (
('Africa', 'Africa'),
('America', 'America'),
('Asia', 'Asia'),
('Europe', 'Europe'),
('Oceania', 'Oceania')
)
region = models.CharField(max_length=255)
continent = models.CharField(max_length=255, choices=CONTINENTCHOICE)
GDP_per_capita = models.IntegerField(null=True)
unemployment_rate = models.FloatField(null=True)
female_unemployment_rate = models.FloatField(null=True)
litteracy_rate = models.FloatField(null=True)
def __str__(self):
return self.country_name
class OutputOutcomeImpact(models.Model):
output_outcome_impact_name = models.CharField(max_length=255, primary_key=True)
TYPECHOICE = (
('Output', 'Output'),
('Outcome', 'Outcome'),
('Impact', 'Impact'),
)
type = models.CharField(max_length=255, choices=TYPECHOICE)
description = models.TextField()
TARGETGROUP = (
('Standard', 'Standard'),
('Investors', 'Investors'),
('Local authorities and NGOs', 'Local authorities and NGOs'),
)
target_group = models.CharField(max_length=255,choices=TARGETGROUP)
question = models.TextField(null=True, blank=True)
parent_name = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True)
indicator = models.ForeignKey(Indicator, on_delete=models.PROTECT)
def __str__(self):
return self.output_outcome_impact_name
class Activity(models.Model):
activity_name = models.CharField(max_length=255, primary_key=True)
description = models.TextField()
product_service = models.TextField()
output_outcome = models.TextField()
outcome_impact = models.TextField()
output_outcome_impacts = models.ManyToManyField('OutputOutcomeImpact')
countries = models.ManyToManyField('Country')
sectors = models.ManyToManyField('Sector')
def __str__(self):
return self.activity_name
class Value(models.Model):
value_name = models.CharField(max_length=255, primary_key=True)
country = models.ForeignKey(Country, on_delete=models.PROTECT)
id_output_outcome_impact = models.ForeignKey(OutputOutcomeImpact, on_delete=models.PROTECT)
value_has_source = models.ManyToManyField('Source')
value = models.FloatField()
function_name = models.CharField(max_length=255, default = "multiply")
def __str__(self):
return self.value_name
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values()
So the result of the query is available below, and what I would like to achieve is to set the value field to an average of every object that has the same id_output_outcome_impact_id, here Dioxins and furans emissions reduction appears twice so I would like to get the 2 values set as their average.
<QuerySet [{'value_name': 'Waste_to_dioxins', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 0.0003, 'function_name': 'multiply'}, {'value_name': 'Waste_to_dioxins_south_africa', 'country_id': 'South Africa', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 150.0, 'function_name': 'multiply'}, {'value_name': 'Households getting electricity per kWh', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Households that get electricity', 'value': 0.0012, 'function_name': 'multiply'}, {'value_name': 'Dioxin to disease', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Reduction of air pollution related diseases', 'value': 0.31, 'function_name': 'multiply'}]>
I am wondering if django models allow such modification (I went through the doc and saw the annotate function with the average but couldn't make it work for my specific case), that would be nice. Thanks.
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values('id_output_outcome_impact__output_outcome_impact_name').annotate(Avg('value'))

business generated has to come based on dcr(daily call report)

I have DCR & SalesMIS model. I want to get the business generated count. And if count is it should return the business_genrated else saleMIS.amount
I wrote a method in DCR model i.e. get_business_generated(self) and apply filter on SaleMIS model. Then trying to get the count of business_generated
ERROR:D:\Projects\Python\Django\kingllp\venv\lib\site-packages\django\db\models\base.py", line 95, in new
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class builtins.DCR doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
This is DCR model
class DCR(models.Model):
STATUSES = (
('1N', 'Need Analysis'),
('2P', 'Proposal Stage'),
('3C', 'Competitive Selling'),
('4D', 'Decision Stage'),
)
prospect = models.ForeignKey(Prospect, on_delete=models.CASCADE, related_name='dcrs')
date = models.DateField(blank=True)
status = models.CharField(choices=STATUSES, max_length=2, default='1N')
discussion_points = models.CharField(max_length=2047, blank=True)
business_generated = models.IntegerField(default=0)
is_new_business = models.BooleanField(default=False)
def get_business_generated(self):
date = self.date
client = self.prospect
sale = SalesMIS.objects.filter(date=date,client = Prospect)
salecount = sale.count()
if salecount==0:
return DCR.business_generated
else:
return SalesMIS.amount
This is SaleMIS model
class SalesMIS(models.Model):
class Meta:
verbose_name_plural = _("Sale MIS")
date = models.DateField()
fls = models.ForeignKey(Employee, blank=True, null=True, on_delete=models.SET_NULL, related_name='sales')
amount = models.DecimalField(max_digits=20, decimal_places=2)
po_number = models.CharField(max_length=255, null=True, blank=True)
products = models.CharField(max_length=255, null=True, blank=True)
client = models.ForeignKey(Client, blank=True, null=True, on_delete=models.SET_NULL, related_name='client_mis')
def __str__(self):
return str(self.date) + ":" + self.fls.full_name()
Business share has to come based on DCR/MIS.

How to serialize list of strings with Django Rest Framework

I have serializer in Django rest framework as follows:
class StateSerializer(serializers.ModelSerializer):
kilometers = Field(source='mileage')
pictures = StatePictureSerializer(many=True, read_only=True)
class Meta:
model = Inspection # Options
fields = ('kilometers', 'inspection_date', 'pictures')
And StatePictureSerializer is as follows:
class StatePictureSerializer(serializers.ModelSerializer):
blob_url = Field(source='public_url')
class Meta:
model = Inspection_Picture
fields = ('blob_url', )
As result I get something as follows:
{
"kilometers": 64431,
"inspection_date": null,
"pictures": [
{"blob_url": "path/to/photo"},
{"blob_url": "path/to/photo"},
{"blob_url": "path/to/photo"},
{"blob_url": "path/to/photo"},
{"blob_url": "path/to/photo"}
]
}
Thus, pictures is an array of objects.
What I want is an array of strings, for example:
"pictures": ["path/to/photo", "path/to/photo", "path/to/photo", "path/to/photo", "path/to/photo"]
Any idea how to do that?
EDIT
Inspection model is as follows:
class Inspection(models.Model):
customerReference = models.CharField(max_length=50, blank=True, null=True)
extraReference = models.CharField(max_length=50, blank=True, null=True)
itemReference = models.IntegerField(blank=True, null=True)
vehicle = models.ForeignKey(to=Vehicle)
mileage = models.IntegerField()
timeStamp = models.DateTimeField(auto_now_add=True)
inspection_date = models.DateTimeField(null=True)
features = models.ManyToManyField(to=Feature)
pictures = models.ManyToManyField(to=Images, through="Inspection_Picture")
damages = models.ManyToManyField(to=Damage)
parts = models.ManyToManyField(to=Part)
checks = models.ManyToManyField(to=CheckType, through=Inspection_Check)
featuresFlat = models.ManyToManyField(to=FeatureFlat, through=Inspection_FeatureFlat)
And Images model is as follows:
class Images(models.Model):
"""Model for storing uploaded photos"""
filename = models.CharField(max_length=255)
extension = models.CharField(max_length=40)
key_data = models.CharField(max_length=90, unique=True, blank=True, null=True)
upload_date = models.DateTimeField(auto_now_add=True)
upload_identification = models.CharField(max_length=50, blank=True, null=True)
url = models.CharField(max_length=1024, blank=True, null=True)
stored = models.BooleanField(default=False)
thumbnailed = models.BooleanField(default=False)
thumbnailed_treated = models.BooleanField(default=False)
protected = models.BooleanField(default=False)
source = models.CharField(max_length=50, blank=True, null=True)
#property
def key_generate(self):
"""returns a string based unique key with length 80 chars"""
while 1:
key = str(random.getrandbits(256))
try:
Images.objects.get(key=key)
except:
return key
def __unicode__(self):
return self.upload_identification
def public_url(self):
return settings.AZURE_URL_FULL + self.url
I think in your case SerializerMethodField would be a right choice as follows. There may be <field_name> mismatch in the code below. Please make it working according your model. I assume the field names based on your serializer above.
class StateSerializer(serializers.ModelSerializer):
kilometers = Field(source='mileage')
pictures = serializers.SerializerMethodField('get_pictures')
class Meta:
model = Inspection # Options
fields = ('kilometers', 'inspection_date', 'pictures')
def get_pictures(self, obj):
return [each.public_url() for each in obj.pictures.all() ]

Get Foreign Key Value

How can I get the foreign key values? I have a common vehicle model that links to the year, series, engine type, body style, transmission and drive train...all as foreign keys. I'd like to get the values of these fields for my app, but I'm stuck as to how I'd go about them. Any ideas will be highly appreciated.
class Model(models.Model):
model = models.CharField(max_length=15, blank=False)
manufacturer = models.ForeignKey(Manufacturer)
date_added = models.DateField()
def __unicode__(self):
name = ''+str(self.manufacturer)+" "+str(self.model)
return name
class Year(models.Model):
ALPHA_NUMERIC_CHOICES = (
('1', 'Numeric'),
('A', 'Alphabetic'),
)
year = models.PositiveSmallIntegerField()
position_7_char = models.CharField(max_length=1, choices=ALPHA_NUMERIC_CHOICES)
position_10 = models.CharField(max_length=1, blank=False)
def __unicode__(self):
return unicode(self.year)
class Series(models.Model):
series = models.CharField(max_length=20, blank=True)
model = models.ForeignKey(Model)
date_added = models.DateField()
def __unicode__(self):
name = str(self.model)+" "+str(self.series)
return name
class CommonVehicle(models.Model):
year = models.ForeignKey(Year)
series = models.ForeignKey(Series)
engine = models.ForeignKey(Engine)
body_style = models.ForeignKey(BodyStyle)
transmission = models.ForeignKey(Transmission)
drive_train = models.ForeignKey(DriveTrain)
def __unicode__(self):
name = ''+str(self.year)+" "+str(self.series)
return name
class Vehicle(models.Model):
stock_number = models.CharField(max_length=6, blank=False)
vin = models.CharField(max_length=17, blank=False)
common_vehicle = models.ForeignKey(CommonVehicle)
exterior_colour = models.ForeignKey(ExteriorColour)
interior_colour = models.ForeignKey(InteriorColour)
interior_type = models.ForeignKey(InteriorType)
odometer_unit = models.ForeignKey(OdometerUnit)
status = models.ForeignKey(Status)
odometer_reading = models.PositiveIntegerField()
selling_price = models.PositiveIntegerField()
purchase_date = models.DateField()
sales_description = models.CharField(max_length=60, blank=False)
def __unicode__(self):
return self.stock_numberodels.ForeignKey(CommonVehicle)
You need the actual IDs? Try something like my_vehicle_ref.series.id.
Also, I hope you know that the series attribute right there is really an instance of Series, so you could access any of it's properties, e.g., my_vehicle_ref.series.model.model.