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"))
# ^^^^^^^
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 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
Suppose i have two models:
class Region(models.Model):
region_name = models.CharField(
max_length=50, null=False, blank=False, unique=True, verbose_name="Region Name"
)
def __str__(self):
return self.region_name
class Meta:
verbose_name_plural = "Regions"
class Country(models.Model):
region_id = models.ForeignKey(
Region,
null=True,
blank=True,
on_delete=models.CASCADE,
verbose_name="Region id",
)
country_name = models.CharField(
max_length=50, unique=True, null=False, blank=False, verbose_name="Country Name"
)
def __str__(self):
return self.country_name
class Meta:
verbose_name_plural = "Countries"
Now, when i access the country model through Djnago REST Framework, as /api/countries
I get country_name and region_id for example
[
{
"id": 1,
"country_name":"Taiwan",
"region_id": 1
},
...
...
]
Is there any way to get the result like:
[
{
"id": 1,
"country_name":"Taiwan",
"region_id": {
id: 1,
region_name: "Asia",
}
},
...
...
]
I have tried nested serializer example as on the DRF website, but it returns a list of countries if we get the regions api.
like:
[
{
"id": 1,
"region_name":"Asia",
"countries":
[
"Taiwan",
"Japan",
"Vietnam",
...
]
},
...
...
]
I need to know the region name of the country in one api get request. Right now i am using 2 requests. One to get country, and then get region name from region id.
This is my model and serializer if i use nested serializer.
class Region(models.Model):
region_name = models.CharField(
max_length=50, null=False, blank=False, unique=True, verbose_name="Region Name"
)
def __str__(self):
return self.region_name
class Meta:
verbose_name_plural = "Regions"
class Country(models.Model):
region_id = models.ForeignKey(
related_name="countries"
Region,
null=True,
blank=True,
on_delete=models.CASCADE,
verbose_name="Region id",
)
country_name = models.CharField(
max_length=50, unique=True, null=False, blank=False, verbose_name="Country Name"
)
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = "__all__"
class RegionSerializer(serializers.ModelSerializer):
countries = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='country_name'
)
class Meta:
model = Region
fields = ["id", "region_name", "countries"]
The reason you only get the slugs of the related Countrys is because you use the SlugRelatedField, that will thus list the slugs of the Countrys.
The trick is to make extra serializers that will serializer the related object(s). For example:
class ShallowRegionSerializer(serializers.ModelSerializer):
class Meta:
model = Region
fields = '__all__'
class CountrySerializer(serializers.ModelSerializer):
region_id = ShallowRegionSerializer()
class Meta:
model = Country
fields = '__all__'
class CountryRegionSerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = '__all__'
class RegionSerializer(serializers.ModelSerializer):
countries = CountryRegionSerializer(
many=True,
read_only=True
)
class Meta:
model = Region
fields = ['id', 'region_name', 'countries']
Now you can make use of the CountrySerializer and the RegionSerializer. When serializing objects, it will use other serializers, like the ShallowRegionSerializer and CountryRegionSerializer to serialize related object(s).
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]
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。