I want to join two tables,
i have model :
Employee :
class Employee(models.Model):
employee_identity = models.CharField(max_length=255, blank=True, null=True)
full_name = models.CharField(max_length=255, blank=True, null=True)
place_birth = models.CharField(max_length=255, blank=True, null=True)
date_birth = models.DateField(blank=True, null=True)
role = models.CharField(max_length=255, blank=True, null=True)
no_hp = models.CharField(max_length=255, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'employee'
Penalty :
class Penalty(models.Model):
employee = models.ForeignKey(Employee,on_delete=models.CASCADE)
type = models.CharField(max_length=255, blank=True, null=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
doc = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'penalty'
My EmployeeSerializer :
class EmployeeSerializer (serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
My PenaltySerializer:
class PenaltySerializer (serializers.ModelSerializer):
class Meta:
model = Penalty
fields = ('employee','type','start_date','end_date')
My expected Penalty result :
"results": [
{
"employee": 14871,
"type": "low",
"start_date": "2018-10-15",
"end_date": "2018-10-16",
"employee_identity": "A1738129",
"full_name": "Full name here",
"role": "staff"
}
]
I have tried to using this in my serializer
class PenaltySerializer (serializers.ModelSerializer):
a = EmployeeSerializer(many=True,read_only=True)
class Meta:
model = Penalty
fields = ('employee','type','start_date','end_date','a')
but the result of 'a' not showed up.
I think this might help
class PenaltySerializer (serializers.ModelSerializer):
employee_identity = serializers.CharField(source="employee.employee_identity")
full_name = serializers.CharField(source="employee.full_name")
role = serializers.CharField(source="employee.role")
class Meta:
model = Penalty
fields = (
'employee',
'type',
'start_date',
'end_date',
'employee_identity',
'full_name',
'role'
)
You can do something like this in your serializer:
class PenaltySerializer (serializers.ModelSerializer):
employee = serializers.SerializerMethodField()
class Meta:
model=Penalty
fields = '__all__'
def get_employee(self, object):
return EmployeeSerializer(object.employee.all(), many=True).data
Related
Relatively new to Django. I'm building a light CRM in Django. The MYSQL database I built uses associative entities to help deal with many-to-many relationships.
I'm trying to use the associative entity "contactdeal" to connect "deals" with "contacts".
See models and views below.
Models:
class Account1(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
city = models.CharField(max_length=255, blank=True, null=True)
state = models.CharField(max_length=255, blank=True, null=True)
country = models.CharField(max_length=255, blank=True, null=True)
description = models.CharField(max_length=255, blank=True, null=True)
phone = models.CharField(max_length=255, blank=True, null=True)
email = models.CharField(max_length=255, blank=True, null=True)
biztype = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'account'
class Contact1(models.Model):
contact_id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
account_id = models.ForeignKey(Account1, models.DO_NOTHING, db_column='account_id', blank=False, null=False)
contact_notes = models.TextField(blank=True, null=True)
contact_email = models.CharField(max_length=255, blank=True, null=True)
contact_phone = models.CharField(max_length=255, blank=True, null=True)
contact_status = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'contact'
class Contactdeal(models.Model):
contactdeal_id = models.AutoField(primary_key=True)
contactdeal_deal_fk = models.ForeignKey('Deal', models.DO_NOTHING, db_column='contactdeal_deal_fk', blank=True, null=True)
contactdeal_contact_fk = models.ForeignKey(Contact1, models.DO_NOTHING, related_name='contactdeal_contact_fk', db_column='contactdeal_contact_fk', blank=True, null=True)
class Meta:
managed = False
db_table = 'contactdeal'
class Deal(models.Model):
deal_id = models.AutoField(primary_key=True)
deal_name = models.CharField(max_length=255, blank=True, null=True)
est_value = models.DecimalField(max_digits=13, decimal_places=2, blank=True, null=True)
deal_notes = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'deal'
View:
def deal(request):
deal = Contactdeal.objects.select_related('contactdeal_contact_fk', 'contactdeal_deal_fk')
template = loader.get_template('deal.html')
context = {
'deal' : deal,
}
return HttpResponse(template.render(context, request))
Template:
{% for x in deal %}
<tbody>
<tr class="table-active">
<td>{{x.contactdeal_deal_fk.deal_name}}</td>
<td>{{x.contactdeal_deal_fk.est_value}}</td>
<td>{{x.contactdeal_contact_fk.first_name}}</td>
<td>{{x.contactdeal_contact_fk.account_id}}</td>
<td>Update</td>
<td>Delete</td>
</tr>
</tbody>
{% endfor %}
for the most part, I've been successful using the select_related approach to join both contacts and deals using the associative entity contactdeal.
Where this falls short, however, is when I want to show the "account" each "contact" belongs to. I can show "account_id" which is the FK that links the "contact" table and "account" table, but I can't seem to come up with a way to add another join that will allow me to use the "account_id" FK in the contact table to pull the name associated with that "account_id" in the "account" table.
I think I figured it out. I am going to try to create a view in MYSQL that achieves the connection I am looking to establish and turn that into its own model, not managed using Django.
I want to enter multiple entries for "item" under one "session_title" - and I think I understand I need a ManyToOne relationship (set with ForeignKey) but mysite/admin isn't showing multiple entries available? I am using DjangoAdmin to administer my app.
Edit/Add: I know there's a step I'm missing. I'm hoping for someone to send me there.
class Item(models.Model):
item_name = models.TextField(unique=True)
class Meta:
managed = True
db_table = 'item'
def __str__(self):
return self.item_name
class SessionLog(models.Model):
date = models.DateField()
session_title = models.TextField(blank=True, null=True)
campaign = models.OneToOneField(Campaign, models.DO_NOTHING, default="1")
chapter = models.OneToOneField(Chapter, models.DO_NOTHING, default="1")
scene = models.OneToOneField(Scene, models.DO_NOTHING, default="1")
character = models.OneToOneField(Character, models.DO_NOTHING, default="1")
location = models.OneToOneField(Location, models.DO_NOTHING, blank=True, null=True)
npc = models.OneToOneField(Npc, models.DO_NOTHING, blank=True, null=True)
monster = models.OneToOneField(Monster, models.DO_NOTHING, blank=True, null=True)
item = models.ForeignKey(Item, models.DO_NOTHING, blank=True, null=True)
loot_pp = models.IntegerField(blank=True, null=True)
loot_gp = models.IntegerField(blank=True, null=True)
loot_ep = models.IntegerField(blank=True, null=True)
loot_sp = models.IntegerField(blank=True, null=True)
loot_cp = models.IntegerField(blank=True, null=True)
session_xp = models.IntegerField(blank=True, null=True)
session_strongstart = models.TextField(blank=True, null=True)
session_secrets = models.TextField(blank=True, null=True)
session_clues = models.TextField(blank=True, null=True)
session_notes = models.TextField(blank=True, null=True)
class Meta:
managed = True
db_table = 'session_log'
def __str__(self):
return self.session_title
Could someone point me in the right direction? Thank you, in advance.
Yep, you're on the right track.
Change
item = models.ForeignKey(Item, models.DO_NOTHING, blank=True, null=True)
to
items = models.ManyToManyField(Item, on_delete=models.DO_NOTHING)
and in your admin, declare an Inline class:
class ItemInline(admin.TabularInline):
pass
class SessionLogAdmin(admin.ModelAdmin):
inlines = [ItemInline]
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)
I ma getting this error while calling save method. the error is Unknown column 'userprofile.id' in 'field list
class Userprofile(models.Model):
user = models.OneToOneField(User)
profile_id = models.IntegerField(db_column='profile_id') # Field namemade lowercase.
f_name = models.CharField(max_length=45, blank=True, null=True)
middle_name = models.CharField(max_length=45, blank=True, null=True)
l_name = models.CharField(max_length=45, blank=True, null=True)
dob = models.DateField(db_column='DOB', blank=True, null=True) # Field namemade lowercase.
contact_number = models.IntegerField(blank=True, null=True)
email = models.CharField(max_length=45, blank=True, null=True)
joining_date = models.DateField(db_column='Joining_date', blank=True, null=True) # Field name made lowercase.
temp_address = models.CharField(max_length=45, blank=True, null=True)
permanant_add = models.CharField(db_column='Permanant_add', max_length=45, blank=True, null=True) # Field name made lowercase.
user_image = models.CharField(max_length=45, blank=True, null=True)
gender_idgender = models.ForeignKey(Gender, models.DO_NOTHING, db_column='gender_idgender')
class Meta:
managed = False
db_table = 'userprofile'
unique_together = (('profile_id', 'gender_idgender'),)
This is my model
“_id” is suffix syntax in django query,You'd better not use it as a field name in your model。
I need some help with this sql query that I am trying to run with django orm model.
SELECT SUM(CAPITAL) AS PRODUCT_CAPITAL, PRODUCT FROM CAPITAL_SHEET
WHERE CLIENT_ID = 'X1234'
GROUP BY PRODUCT
I did this
CapitalSheet.objects.filter(client_id="X1234").values("product").annotate(Sum("capital"))
This is what I am getting as a result in json:
[
{
"product": "product1"
},
{
"product": "product2"
}
]
I was expecting this as output :
[
{
"product": "product1",
"capital": 1234.00
},
{
"product": "product2",
"capital": 1234.00
}
]
here is my view:
class CapitalListView(ListAPIView):
serializer_class = CapitalSheetSerializer
def get_queryset(self):
return CapitalSheet.objects.filter(client_id="X1234").values("product").annotate(Sum("capital"))
Here are my models:
class CapitalSheet(models.Model):
log_id = models.AutoField(db_column='LOG_ID', primary_key=True)
client_id = models.CharField(db_column='CLIENT_ID', max_length=25)
capital = models.DecimalField(db_column='CAPITAL', max_digits=10, decimal_places=2, blank=True, null=True)
payout_booked_profit = models.DecimalField(db_column='PAYOUT_BOOKED_PROFIT', max_digits=10, decimal_places=2, blank=True, null=True)
voucher_number = models.CharField(db_column='VOUCHER_NUMBER', max_length=45, blank=True, null=True)
ledger_date = models.DateField(db_column='LEDGER_DATE', blank=True, null=True)
amount = models.DecimalField(db_column='AMOUNT', max_digits=10, decimal_places=2, blank=True, null=True)
product = models.CharField(db_column='PRODUCT', max_length=45, blank=True, null=True)
transaction_type = models.CharField(db_column='TRANSACTION_TYPE', max_length=45, blank=True, null=True)
sebi_payin_flag = models.IntegerField(db_column='SEBI_PAYIN_FLAG', blank=True, null=True)
dividend_payout_flag = models.IntegerField(db_column='DIVIDEND_PAYOUT_FLAG', blank=True, null=True)
My serializer:
class CapitalSheetSerializer(serializers.ModelSerializer):
class Meta:
model = CapitalSheet
fields = ['capital','product']
What am i doing wrong here ?
try it, add name for annotate column:
CapitalSheet.objects.filter(
client_id="X1234"
).values("product").annotate(capital=Sum("capital"))
# ^^^^^^^