In Django views, I want to fetch all details(Workeraccount.location,Workeravail.date, Workerprofile.*) for any particular wid=1.
SQL Query:
select * from Workeraccount,Workeravail,Workerprofile where Workerprofile.wid=1 and Workerprofile.wid=Workeravail.wid and Workeraccount.wid=Workerprofile.wid;
The corresponding models are as follows:
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True)
location = models.ForeignKey(Location, db_column='location')
class Meta:
managed = False
db_table = 'workerAccount'
class Workeravail(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid')
date = models.DateField()
class Meta:
managed = False
db_table = 'workerAvail'
class Workerprofile(models.Model):
wid = models.SmallIntegerField(primary_key=True)
fname = models.CharField(max_length=30)
mname = models.CharField(max_length=30, blank=True, null=True)
lname = models.CharField(max_length=30)
gender = models.CharField(max_length=1)
age = models.IntegerField()
class Meta:
managed = False
db_table = 'workerProfile'`
You can do this:
workprofile = Workerprofile.objects.filter(id=1).first()
all_worker_avails = workprofile.workeravail_set.all()
all_workeraccounts = workprofile.workeraccount_set.all()
As Workeraccount and Workeravail are related through Workerprofile, you can get one queryset easily - you will need two separate ones.
You can also do the following:
all_worker_avails = Workeravail.objects.filter(wid=workprofile)
...
Here is how you can do it with only one database call:
workprofile = Workerprofile.objects.get(pk=1)
.select_related('workeravail_set', 'workerprofile_set')
This will fetch all the data for you at once, which can then be used with:
workprofile.workerprofile_set.location #Gets the Workeraccount.location
workprofile.workeravail_set.date #Gets the Workeravail.date
workprofile.fname #Example of Workerprofile.*
As an aside, if you want a shorter way to reference the foreign objects than the "*_set" method, you can set a related_name like
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True, related_name='waccount')
...
And then replace workeraccount_set with waccount
Related
Basically i want to have fk_inventory as a nested field in StorageRackSerializer but as you guys can see I also need to use StorageRackSerializer in InventorySerializer.
How can i set the field after creating the serializer class?
I have tried creating a fk_inventory field and set it to None and tried to set to InventorySerializer afterwards but didn't work.
class Inventory(models.Model):
inventory_id = models.AutoField(primary_key=True)
fk_building = models.OneToOneField(Store, on_delete=models.CASCADE, unique=True, related_name='inventory')
def __str__(self):
return f"{self.inventory_id}"
class StorageRack(models.Model):
storage_rack_id = models.AutoField(primary_key=True)
quantity = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(50)])
fk_inventory = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name="storage_racks")
fk_product_id = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True, related_name="storage_racks")
def __str__(self):
return f"{self.storage_rack_id}"
class StorageRackSerializer(serializers.ModelSerializer):
fk_product_id = ProductSerializer(read_only=True)
fk_inventory = None
class Meta:
model = StorageRack
fields = ('storage_rack_id', 'quantity', 'fk_inventory', 'fk_product_id')
class InventorySerializer(serializers.ModelSerializer):
fk_building = StoreSerializer()
storage_racks = StorageRackSerializer(many=True)
class Meta:
model = Inventory
fields = ('inventory_id', 'fk_building', 'storage_racks')
StorageRackSerializer.fk_inventory = InventorySerializer()
You can add a field 'fk_inventory' in the validated data from SorageRackSerializer
validated_data = StorageRackSerializer(data=data)
validated_data['fk_inventory'] = InventorySerializer().data
class ProductSerizer(serializers.ModelSerializer):
category = serializers.PrimaryKeyRelatedField(queryset=Category.objects)
title_of_product = serializers.CharField(required=True)
slug = serializers.SlugField(required=True)
image_of_product = serializers.ImageField(required=True)
description_of_product = serializers.CharField(required=True)
price_of_product = serializers.DecimalField(max_digits=12, decimal_places=2, required=True)
class Product(models.Model):
class Meta:
abstract = True
category = models.ForeignKey(Category, verbose_name="category", on_delete=models.CASCADE)
title_of_product = models.CharField(max_length=225,verbose_name="Title",null=True)
slug = models.SlugField(unique=True)
image_of_product = models.ImageField(verbose_name="Image", null=True)
description_of_product = models.TextField(verbose_name = "Descripwtion", null = True)
price_of_product = models.DecimalField(max_digits=10,decimal_places=2, verbose_name="Price", null=True)
and I want to list all elements from categories, but I cannot serialize this class. How should I do ?
Take a look at this thread, which talks about abtract models and how to serialize them
I am trying to join multiple table using django ORM .i have tried several different way but no luck.
from django.db import models
from compositefk.fields import CompositeForeignKey, CompositeOneToOneField
class Company(models.Model):
code = models.DecimalField(db_column='Code', max_digits=38, decimal_places=0)
srccode = models.SmallIntegerField(db_column='SrcCode')
est = models.DateTimeField(db_column='Est')
rownum = models.BigIntegerField(db_column='RowNum')
class Meta:
manage = False
unique_together = (('code', 'srccode'),)
db_table = 'Company'
class Floor(models.Model):
code = models.DecimalField(db_column='Code', max_digits=38, decimal_places=0)
srccode = models.SmallIntegerField(db_column='SrcCode')
depcode = models.DecimalField(db_column='DepCode', max_digits=38, decimal_places=0)
depsrccode = models.SmallIntegerField(db_column='Depsrccode')
floorname = models.CharField(db_column='FloorName')
rownum = models.BigIntegerField(db_column='RowNum')
company = CompositeForeignKey(Company,on_delete=models.CASCADE,to_fields={'code':'code','srccode': 'srccode'})
department= CompositeOneToOneField(Department,on_delete=models.CASCADE,to_fields={'depcode':'depcode','depsrccode': 'depsrccode'})
class Meta:
manage = False
unique_together = (('depcode', 'depsrccode','floorname'),)
db_table = 'floor'
class SubCompany(models.Model):
code = models.DecimalField(db_column='Code', max_digits=38, decimal_places=0)
srccode = models.SmallIntegerField(db_column='SrcCode')
subname = models.CharField(db_column='SubName')
rownum = models.BigIntegerField(db_column='RowNum')
location = models.CharField(db_column='Location')
department = models.CharField(db_column='Department')
company = CompositeForeignKey(Company,on_delete=models.CASCADE,to_fields={'code':'code','srccode': 'srccode'})
class Meta:
manage = False
unique_together = (('code', 'srccode','subname','rownum'),)
db_table = 'SubCompany'
basically i am trying to get data as per below row sql
SELECT Location, Department, Subname, t.* from [Floor] t join [SubCompany] s on t.code = s.code and t.srccode = s.srccode;"
what is the equilant Django Orm of above SQL query.?
is there any alternative solution apart from raw sql in django.?
Thanks
My input json is :
{
"availability": "Current",
"drive_type": [{
"drive_name": "drive1",
"requirements": {
"performance_unit": "by_iops",
}
}]
}
I am getting error Cannot assign "
OrderedDict([('performance_unit', 'Basic')])":
"DriveType.requirements" must be a "Requirements" instance
.I am not able to figure it out to map in create method for one to one fields in tables
Below are my models.py
class ProductLine(models.Model):
availability = models.CharField(max_length=20, blank=True, null=True)
class Meta:
db_table = "product_line"
class DriveType(models.Model):
drive_name = models.CharField(max_length=20, blank=True, null=True)
product_line = models.ForeignKey(ProductLine, related_name="drive_type")
class Meta:
db_table = "drive_type"
class Requirements(models.Model):
performance_unit = models.CharField(max_length=100, blank=True, null=True)
drive_type = models.OneToOneField(DriveType,on_delete=models.CASCADE,primary_key=True,related_name="requirements")
class Meta:
db_table = "requirements"
Serializers.py :
class DriveTypeSerializer(serializers.ModelSerializer):
requirements = RequirementsSerializer(many = True)
class Meta:
model = DriveType
fields = (
"drive_name","workload_type")
class ProductLineSerializer(serializers.ModelSerializer):
drive_type = DriveTypeSerializer(many=True)
class Meta:
model = ProductLine
fields = ('availability', "drive_type")
def create(self, validated_data):
print("validate_data",validated_data)
drive_type_data = validated_data.pop("drive_type")
product_line = ProductLine.objects.create(**validated_data)
for drive_data in drive_type_data:
drive_type = DriveType.objects.create(product_line=product_line, **drive_data)
return product_line
You have one to one relationship of DriveType and Requirements
So remove many = True from DriveTypeSerializer for RequirementsSerializer
class DriveTypeSerializer(serializers.ModelSerializer):
requirements = RequirementsSerializer()
class Meta:
model = DriveType
fields = ("drive_name","workload_type")
Your input json has only one object of requirements not a list
I want create product element and redirect to him page
def newprodcreate(request, c_id):
if models.company.objects.get(email = request.user.username).id == int(c_id):
name = request.POST['newprodname']
comp = models.company.objects.get(id = int(c_id))
prod = models.product()
prod.name = name
prod.comp_id = int(c_id)
prod.address = comp.address
prod.lat = comp.lat
prod.lng = comp.lng
prod.phone = comp.phone
prod.cur_id = 2
prod.save()
return HttpResponseRedirect("/p/" + str(prod.id))
the element created in database, but prod.id is Null
model:
class product(models.Model):
class Meta:
db_table = "product"
id = models.IntegerField(primary_key=True)
crdate = models.DateTimeField(default = datetime.now())
comp_id = models.IntegerField()
categ = models.CharField(max_length=200, default="")
img = models.FileField(upload_to=MEDIA_ROOT +"/product/", max_length=200)
name = models.CharField(max_length=200)...
Dear michael in django ORM for creating autho field or serial field which used for id primary key or etc we use Autofield instead of integer field .
id = models.AutoField(primary_key=True)
your model in corrected state:
class product(models.Model):
class Meta:
db_table = "product"
id = models.AutoField(primary_key=True)
crdate = models.DateTimeField(default =
datetime.now())
comp_id = models.IntegerField()
categ = models.CharField(max_length=200, default="")
img = models.FileField(upload_to=MEDIA_ROOT. +"/product/", max_length=200)
name = models.CharField(max_length=200)...
For django models There will be a default field with name "id" which is auto increment field. you have override that id with IntegerField that is id = models.IntegerField(primary_key=True)
So you have to provide id explicitly every time when you create product object
Better solution is to change id IntegerField to AutoField
id = models.AutoField(primary_key=True)
Then your id will be created automatically no need to pass id every time you create new object.