I have the following tables. The ComponentBuild table has two columns 'comp_pn' and 'parent_pn' that are both ForeignKeys. Django is complaining Unknown column 'product_parent_pn.product_id_id. What's the correct way to model these relationship?
class Product(models.Model):
name = models.CharField(max_length=80)
def __unicode__(self):
return self.name
class ProductParentPn(models.Model):
part_no = models.CharField(max_length=80)
product_id = models.ForeignKey(Product)
def __unicode__(self):
return self.part_no
class CompMap(models.Model):
component = models.CharField(max_length=50)
part_no = models.CharField(max_length=50)
def __unicode__(self):
return self.part_no
class CompProductMap(models.Model):
comp_id = models.IntegerField()
prod_id = models.IntegerField()
class Meta:
db_table = u'comp_product_map'
class ComponentBuild(models.Model):
comp_sn = models.CharField(max_length=35)
parent_sn = models.CharField(max_length=15)
comp_pn = models.ForeignKey(CompMap)
parent_pn = models.ForeignKey(ProductParentPn)
date = models.DateField(default=datetime.datetime.today())
def __unicode__(self):
return self.comp_sn
Related
Trying to fetch a function from a table that is supposed to be there, but cannot get the value. Trying to get the amount of task that is completed.
models.py
class Task(models.Model):
title = models.CharField(max_length=55, null=True, blank=True)
slug = models.SlugField(max_length=500, unique=True, blank=True)
task_completed = models.BooleanField(default=False)
description = models.TextField(default="Task description")
start_date = models.DateTimeField()
due_date = models.DateTimeField()
checklist = models.ManyToManyField(Checklist, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Task, self).save(*args, **kwargs)
def get_url(self):
return reverse('checklists', kwargs={
'slug':self.slug
})
def __str__(self):
return self.title
#property
def num_task_completed(self):
return self.task_completed.count()
class Project(models.Model):
project_manager = models.ForeignKey(Profile, on_delete=CASCADE)
title = models.CharField(max_length=55, null=True, blank=True)
developers = models.ManyToManyField(Profile, related_name='projects')
slug = models.SlugField(max_length=500, unique=True, blank=True)
description = models.TextField(default="Project description")
date = models.DateTimeField(auto_now_add=True)
start_date = models.DateTimeField()
due_date = models.DateTimeField()
tasks = models.ManyToManyField(Task, blank=True)
teams = models.ManyToManyField(Team, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Project, self).save(*args, **kwargs)
def get_url(self):
return reverse('project_detail', kwargs={
'slug':self.slug
})
def __str__(self):
return self.title
#property
def num_task(self):
return self.tasks.count()
Then in the html is just loop through all projects
{% for projects in projects.all %}
<span class="text-small"> {{ projects.tasks.num_task_completed }} /{{ projects.num_task }}</span>
I manage to get the amount of tasks, but not the amount completed.
Use self.tasks.filter(task_completed = True).count() to get the number of completed tasks in a project.
This is my models.py:
class UnitOfMeasurement(models.Model):
active = models.BooleanField(default=True)
name = models.CharField(max_length=255)
measurement_type = models.CharField(max_length=255)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=250)
abbreviation=models.CharField(max_length=10)
active = models.BooleanField(default=True)
description=models.CharField(max_length=500,blank=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
active = models.BooleanField(default=True)
bar_code = models.CharField(max_length=50, blank = True, null = True)
name = models.CharField(max_length=250)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, related_name='product')
brand = models.CharField(max_length=250)
model = models.CharField(max_length=250)
tag = models.CharField(max_length=250, null=True)
remarks = models.TextField(null=True)
gstcode = models.ForeignKey(
GSTCode, on_delete=models.CASCADE, related_name='product', null=True)
unit_of_measurement = models.ForeignKey(
UnitOfMeasurement, on_delete=models.DO_NOTHING, related_name='category')
# picture
objects=ProductManager()
# select the product where active=true & quantity<0
def __str__(self):
return self.name
So how do I need to code my serializers and views in order to get the data that returns name, category, brand, model, tag from Product Model and name from Category Model and also name and measurement_type from UnitOfMeasurement Model?
You can select fields from model in serializer as below example code for UnitOfMeasurement and use this serializer for get(retrieve) request.
class UnitOfMeasurementSerializer(serializers.ModelSerializer):
class Meta:
model = UnitOfMeasurement
fields = ["name", "measurement_type"]
Same thing you can do for rest of models.
Views depends on your use case.
These are my django models.
explaination of db models :
thinkpad is a equipment of laptop subcategory.and laptop subcategory has a category called electronics.
now laptop can have many attributes like processor,ram,color,screen_size.
Question :
Find out all the equipment with theirequipment detail ,subcategory_name and attribute names,value which have category_id =1 .
Models :
class Category(models.Model):
category_id = models.AutoField(primary_key=True, default=None)
category_name = models.CharField(max_length=15, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.category_id)+","+self.category_name
class Meta:
db_table = "category"
class Subcategory(models.Model):
subcategory_id = models.AutoField(primary_key=True, default=None)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, related_name="category_subc", verbose_name="category_id")
subcategory_name = models.CharField(max_length=15, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.subcategory_id)+","+self.subcategory_name
class Meta:
db_table = "subcategory"
class Equipment(models.Model):
equipment_id = models.AutoField(primary_key=True, default=None)
subcategory = models.ForeignKey(
Subcategory, on_delete=models.CASCADE, related_name="subcategory_eq", verbose_name="subcategory_id")
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.equipment_id)
class Meta:
db_table = "equipment"
class Attribute(models.Model):
attribute_id = models.AutoField(primary_key=True, default=None)
attribute_name = models.CharField(max_length=15, unique=True)
subcategory = models.ManyToManyField(
Subcategory, through="SubcategoryAttributeMap")
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.attribute_id)+","+self.attribute_name
class Meta:
db_table = "attribute"
class SubcategoryAttributeMap(models.Model):
id = models.AutoField(primary_key=True, default=None)
subcategory = models.ForeignKey(
Subcategory, on_delete=models.CASCADE, related_name="subcategory_sub_attr_map", verbose_name="subcategory_id")
attribute = models.ForeignKey(
Attribute, on_delete=models.CASCADE, related_name="attribute_sub_attr_map", verbose_name="attribute_id")
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.id)
class Meta:
db_table = "subcategory_attribute_map"
class EquipmentDetail(models.Model):
equipment_detail_id = models.AutoField(primary_key=True, default=None)
equipment = models.ForeignKey(
Equipment, on_delete=models.CASCADE, related_name="equipment_eqdetail", verbose_name="equipment_id")
attribute = models.ForeignKey(
Attribute, on_delete=models.CASCADE, related_name="attribute_eqdetail", verbose_name="attribute_id")
value = models.CharField(max_length=15)
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.equipment_detail_id)+","+self.value
class Meta:
db_table = "equipment_detail"
Desired Output:
[
{
'equipment_id':1,
'subcategory__name':'laptop',
'attribute_detail':[
{
'attribute_name':'color',
'attribute_value':'red'
},
{
'attribute_name':'ram',
'attribute_value':'6gb'
}
]
},
{ 'equipment_id':2,
'subcategory__name':'Mouse',
'attribute_detail':[
{
'attribute_name':'color',
'attribute_value':'red'
},
{
'attribute_name':'dpi',
'attribute_value':'800'
}
]
}
]
Try this:
equipments= Equipment.objects.select_related('subcategory').filter(subcategory__category_id=1).prefetch_related(Prefetch('equipment_eqdetail', EquipmentDetail.objects.select_related('attribute')))
results = []
for equipment in equipments:
temp = {
'equipment_id': equipment.id,
'subcategory__name': equipment.subcategory.name,
}
attributes = []
for eq_detail in equipment.equipment_eqdetail.all():
attributes.append({'attribute_name': eq_detail.attribute.attribute_name, 'attribute_value': eq_detail.value})
temp['attribute_detail'] = attributes
results.append(temp)
There will be 2 sql queries for this lookup and this will return data in your desired format.
I got the answer for this .
equipments = Equipment.objects.filter(subcategory__category__category_id=1)
all_equipments_data = []
# iterate over each equipment
for equipment in equipments:
single_equipment_data = {}
single_equipment_data['equipment_id'] = equipment.equipment_id
single_equipment_data['subcategory__name'] = equipment.subcategory.subcategory_name
attributes_detail_of_equipment = []
# iterate over each equipmentdetail of single equipment
for eqdetail in equipment.equipment_eqdetail.all():
attributes_detail_of_equipment.append({'attribute_name':eqdetail.attribute.attribute_name,'attribute_value':eqdetail.value})
single_equipment_data['attribute_detail'] = attributes_detail_of_equipment
all_equipments_data.append(single_equipment_data)
Try to serialize this Models
Model:
class Order (models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
summ =models.CharField(max_length=15,default='0')
delivery = models.ForeignKey('Delivery')
success = models.BooleanField(default=False)
paymentMethod = models.ForeignKey('Payments')
def __unicode__(self):
return unicode(self.id)
class OrderProduct(models.Model):
order=models.ForeignKey('Order')
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
price = models.IntegerField()
product = models.ForeignKey('product.Product')
additionals = models.IntegerField(null=True,default=0)
count = models.IntegerField()
def __unicode__(self):
return self.id
class Delivery(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
delivery_time = models.DateTimeField()
delivery_adress = models.TextField()
phone = models.TextField()
def __unicode__(self):
return self.phone
class Payments(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
title = models.TextField();
def __unicode__(self):
return self.title
Serializers:
class DeliverySerializer(serializers.ModelSerializer):
class Meta:
model = Delivery
fields = ('id', 'delivery_time','delivery_adress','phone')
def create(self, validated_data):
return Delivery.objects.create(**validated_data)
class PaymentsSerializer(serializers.ModelSerializer):
class Meta:
model = Payments
fields = ('id', 'title')
def create(self, validated_data):
return Payments.objects.create(**validated_data)
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer(read_only=True)
paymentMethod = PaymentsSerializer(read_only=True)
class Meta:
model = Order
fields = ('id', 'delivery', 'paymentMethod','summ','success')
def create(self, validated_data):
deliverys_data = validated_data.pop('delivery')
paymentsMethod_data = validated_data.pop('paymentMethod')
order = Order.objects.create(**validated_data)
for delivery_data in deliverys_data:
Delivery.objects.create(order=order, **delivery_data)
for paymentMethod_data in paymentsMethod_data:
Payments.objects.create(order=order, **paymentMethod_data)
return order
View:
#api_view(['POST'])
def order_post(request, format=None):
#List all snippets, or create a new snippet.
if request.method == 'POST':
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I need to get data by 1 packet, and then write data in DB
EveryTime I get a error:
deliverys_data = validated_data.pop('delivery')
KeyError: 'delivery'
Example of JSON packet
[{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}]
You are getting KeyError: 'delivery' because you have set delivery field as read_only. If DRF finds this field in the input, it will ignore that field.
From docs on read_only argument:
Read-only fields are included in the API output, but should not be
included in the input during create or update operations. Any
'read_only' fields that are incorrectly included in the serializer
input will be ignored.
Also, since you are using paymentMethod field in the create() method, you need to tell DRF to consider that field also in the input.
So, you need to remove the read_only argument from your serializer for both delivery and paymentMethod fields so that these fields are considered when deserializing.
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer() # remove read_only argument
paymentMethod = PaymentsSerializer() # remove read_only argument
Secondly, you are sending the data incorrectly. You need to send a single order input instead of list of orders you are sending.
# send without the list
{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}
EveryTime I get a error: deliverys_data = validated_data.pop('delivery') KeyError: 'delivery'
This is to be expected since the OrderSerialzier has DeliverySerializer flagged as read_only.
If you want to get the data writable, you'll need to remove that flag first.
When I update/delete some content through views.py file i.e via the website, everything works fine but when I try to update some data through admin panel i get this error:
IntegrityError at /admin/library/student/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (kt2.django_admin_log, CONSTRAINT django_admin_log_user_id_52fdd58701c5f563_fk_auth_user_id FOREIGN KEY (user_id) REFERENCES auth_user (id))')
where kt2 is the name of my database.
Please help and also let me know if you need the code.
models.py
# Create your models here.
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class Student(AbstractUser):
roll_number = models.CharField(max_length=30,unique=True)
student_name = models.CharField(max_length=200)
branch = models.CharField(max_length=20)
sem = models.IntegerField()
pic = models.ImageField(null=True,blank=True)
due_fine = models.IntegerField(default=0)
USERNAME_FIELD='roll_number'
REQUIRED_FIELDS=['username','email']
def __str__(self):
return self.student_name
class Author(models.Model):
author_name = models.CharField(max_length=200,primary_key=True)
def __str__(self):
return self.author_name
class Quantity(models.Model):
q_id=models.AutoField(primary_key=True)
book_name=models.CharField(max_length=200)
list_of_authors=models.ManyToManyField(Author)
qty = models.IntegerField(default=1)
class Meta:
verbose_name_plural = 'Quantity'
# unique_together=(('book_name','list_of_authors'),)
def __str__(self):
return self.book_name
class LastFiveIssues(models.Model):
lfi_id=models.AutoField(primary_key=True)
one_st=models.CharField(max_length=30,blank=True,null=True)
two_st=models.CharField(max_length=30,blank=True,null=True)
three_st=models.CharField(max_length=30,blank=True,null=True)
four_st=models.CharField(max_length=30,blank=True,null=True)
five_st=models.CharField(max_length=30,blank=True,null=True)
issue_one_date=models.DateField(blank=True,null=True)
issue_two_date=models.DateField(blank=True,null=True)
issue_three_date=models.DateField(blank=True,null=True)
issue_four_date=models.DateField(blank=True,null=True)
issue_five_date=models.DateField(blank=True,null=True)
return_one_date=models.DateField(blank=True,null=True)
return_two_date=models.DateField(blank=True,null=True)
return_three_date=models.DateField(blank=True,null=True)
return_four_date=models.DateField(blank=True,null=True)
return_five_date=models.DateField(blank=True,null=True)
class Meta:
verbose_name_plural='last five issues'
class Publisher(models.Model):
publisher_name = models.CharField(max_length=200,primary_key=True)
def __str__(self):
return self.publisher_name
class Book(models.Model):
last_five_issues=models.OneToOneField(LastFiveIssues)
publisher_book=models.ForeignKey(Publisher)
authors = models.ForeignKey(Quantity)
student = models.ForeignKey(Student)
book_id = models.CharField(primary_key=True,max_length=30)
is_issued = models.BooleanField(default=False)
dep_book = models.CharField(max_length=20)
book_name = models.CharField(max_length=200)
date_of_issue = models.DateField(default = '1900-1-1')
return_date = models.DateField(default='1900-1-1')
book_added_on = models.DateField(default='1900-1-1')
placed_at_shelf=models.CharField(max_length=200,blank=True,null=True)
edition_of_book = models.IntegerField()
rare_book = models.BooleanField(default=False)
claim_one=models.CharField(max_length=30,blank=True,null=True)
claim_two=models.CharField(max_length=30,blank=True,null=True)
claim_three=models.CharField(max_length=30,blank=True,null=True)
def __str__(self):
return self.book_name