I get an error when I add a percentage symbol in the query:
Exception Type:IndexError
Exception Value:tuple index out of range.
views.py
class groupdatagercekzamanliveriListView(ListAPIView):
query2 = gercekzamanlıveri.objects.raw("""SELECT 1 as id,
CONCAT(ROUND((SUM(net_uretim_miktari)/SUM(teorik_uretim_miktari)::float*100)),'%') as tee, FROM tee_gercekzamanlıveri
INNER JOIN tee_isyerleri ON tee_gercekzamanlıveri.isyeri_id= tee_isyerleri.id
INNER JOIN tee_malzemeler ON tee_gercekzamanlıveri.malzeme_id= tee_malzemeler.id
INNER JOIN tee_isyerimalzemebilgileri ON tee_isyerimalzemebilgileri.isyeri_id= tee_gercekzamanlıveri.isyeri_id
AND tee_isyerimalzemebilgileri .malzeme_id = tee_gercekzamanlıveri.malzeme_id) as a GROUP BY isyeri_id""")
queryset = query2
serializer_class = groupdatagercekzamanlıveriserializer
serializer.py
class groupdatagercekzamanlıveriserializer(serializers.Serializer):
id = serializers.IntegerField()
tee = serializers.CharField()
When I use "a" as string for "%" no problem:
CONCAT(ROUND((SUM(net_uretim_miktari)/SUM(teorik_uretim_miktari)::float*100)),'a') as tee
Result: "tee": 80a
According to the documentation (GIYF first hit for django sql "%" - at least for me) you have to double it to have the character recognized as a literal, e.g.:
--
CONCAT(
ROUND(
(SUM(net_uretim_miktari) / SUM(teorik_uretim_miktari)::float * 100)
),
'%%'
) as tee, FROM tee_gercekzamanlıveri
--
Related
We have two models. I'm implementing partitioning on the PaymentModel. It gives an error when I want to add to the BuyerModel table linked to this table;
insert or update on table "betik_app_payment_buyermodel" violates
foreign key constraint
"betik_app_payment_bu_payment_id_d7022880_fk_betik_app" DETAIL: Key
(payment_id)=(2) is not present in table
"betik_app_payment_paymentmodel".
models.py
#architect.install('partition', type='range', subtype='date', constraint='month', column='dt')
class PaymentModel(models.Model):
class Meta:
app_label = 'betik_app_payment'
indexes = [
models.Index(fields=['user_email'])
]
payment_status = models.PositiveIntegerField(default=1)
price = MoneyField(max_digits=20, decimal_places=2)
dt = models.DateTimeField()
user_email = models.EmailField(null=True, blank=True)
token = models.CharField(max_length=255, null=True, blank=True)
class BuyerModel(models.Model):
class Meta:
app_label = 'betik_app_payment'
indexes = [
models.Index(fields=['name', 'surname'])
]
payment = models.OneToOneField(to='betik_app_payment.PaymentModel', on_delete=models.CASCADE,related_name='buyer')
name = models.CharField(max_length=100)
surname = models.CharField(max_length=100)
email = models.EmailField(null=True, blank=True)
ip = models.GenericIPAddressField(null=True, blank=True)
main.py
from datetime import datetime
from djmoney.money import Money
buyer_name="Name"
buyer_surname="Surname"
buyer_email="developer#betik.com.tr"
buyer_ip="10.0.0.1"
price= Money("100.00","TRY")
payment_instance = PaymentModel.objects.create(
price=price,
dt=datetime.now(),
user_email=buyer_email
)
# raise error at here
buyer_instance = BuyerModel.objects.create(
payment=payment_instance,
name=buyer_name,
surname=buyer_surname,
email=buyer_email,
ip=buyer_ip
)
using library:
money
partition
I'm looking at the tables in the database with the pgadmin tool and the partition has been applied successfully.
data added in both tables. But BuyerModel table is empty
PaymentModel table has two triggers. These triggers are created automatically by the architect library. Maybe there is an error here?;
after_insert_betik_app_payment_paymentmodel_trigger.
-- FUNCTION: public.betik_app_payment_paymentmodel_delete_master()
-- DROP FUNCTION IF EXISTS public.betik_app_payment_paymentmodel_delete_master();
CREATE OR REPLACE FUNCTION public.betik_app_payment_paymentmodel_delete_master()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
DELETE FROM ONLY "betik_app_payment_paymentmodel" WHERE id = NEW.id;
RETURN NEW;
END;
$BODY$;
ALTER FUNCTION public.betik_app_payment_paymentmodel_delete_master()
OWNER TO postgres_user;
before_insert_betik_app_payment_paymentmodel_trigger.
-- FUNCTION: public.betik_app_payment_paymentmodel_insert_child()
-- DROP FUNCTION IF EXISTS public.betik_app_payment_paymentmodel_insert_child();
CREATE OR REPLACE FUNCTION public.betik_app_payment_paymentmodel_insert_child()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF SECURITY DEFINER
AS $BODY$
DECLARE
match "betik_app_payment_paymentmodel"."dt"%TYPE;
tablename VARCHAR;
checks TEXT;
BEGIN
IF NEW."dt" IS NULL THEN
tablename := 'betik_app_payment_paymentmodel_null';
checks := '"dt" IS NULL';
ELSE
match := DATE_TRUNC('month', NEW."dt");
tablename := 'betik_app_payment_paymentmodel_' || TO_CHAR(NEW."dt", '"y"YYYY"m"MM');
checks := '"dt" >= ''' || match || ''' AND "dt" < ''' || (match + INTERVAL '1 month') || '''';
END IF;
BEGIN
EXECUTE 'CREATE TABLE IF NOT EXISTS ' || tablename || ' (
CHECK (' || checks || '),
LIKE "betik_app_payment_paymentmodel" INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES
) INHERITS ("betik_app_payment_paymentmodel");';
EXCEPTION WHEN duplicate_table THEN
-- pass
END;
EXECUTE 'INSERT INTO ' || tablename || ' VALUES (($1).*);' USING NEW;
RETURN NEW;
END;
$BODY$;
ALTER FUNCTION public.betik_app_payment_paymentmodel_insert_child()
OWNER TO postgres_user;
I have a Item model with a numeric number field. This number field defaults to null.
# models.py
class Item(models.Model):
number = models.IntegerField(default=None, blank=True, null=True)
I want to set-up filters that can return a queryset of Items where number is in range - which is straightforward enough:
# filters.py
class ItemFilter(django_filters.FilterSet):
min_num = django_filters.NumberFilter(method="min_num_filter")
max_num = django_filters.NumberFilter(method="max_num_filter")
class Meta:
model = Item
fields = ("min_num", "max_num", "incl_null")
def min_num_filter(self, queryset, name, value):
return queryset.filter(number__gte=value)
def max_num_filter(self, queryset, name, value):
return queryset.filter(number__lte=value)
But what if I want to have an additional Boolean filter that can include Items that has null for number along with whatever Items matches the min_num and max_num range?
So for example, a URL query in the form of ?min_num=1&max_num=10&incl_null=True should return all Items where number is between 1 and 10 OR number is equal to None.
The following code does not work:
class ItemFilter(django_filters.FilterSet):
...
incl_null = django_filters.BooleanFilter(method="incl_null_filter")
class Meta:
model = Item
fields = ("min_num", "max_num", "incl_null")
// doesn't work
class incl_null_filter(self, queryset, name, value):
if value is True:
return queryset | Item.objects.filter(number=None)
if value is False:
return queryset
Edit: I've tried the methods in the "Filtering by empty values" documentation but I think that's for null values exclusively - where I'm looking for a range match OR a null value.
Try this query:
from django.db.models import Q
min_ = 0
max_ = 10
Item.objects.filter(Q(number__gte=min_, number__lte=max_) | Q(number__isnull=True))
Well, the only solution I can think of is to pass the min range, max range, and is_null boolean into a single char field then convert it into the 3 individual filters for actioning.
So the query URL will look like ?master_num=1-10-1 for range 1 - 10 incl. None and ?master_num=1-10-0 for range 1 - 10 excl. None.
class ItemFilter(django_filters.FilterSet):
master_num = django_filters.CharFilter(method="master_num_filter")
class Meta:
model = Item
fields = ("master_num")
def master_num_filter(self, queryset, name, value):
# array = [min, max, 1 or 0 for True and False]
array = value.split("-")
min = Q(year_published__gte=int(array[0]))
max = Q(year_published__lte=int(array[1]))
if array[2] == "1":
incl_null = Q(year_published=None)
return queryset.filter((min & max) | incl_null)
else:
return queryset.filter(min & max)
Would like to know if there's a better way to do this.
I have a table TickerStatement, which contains financial statements about companies
class Statements(models.TextChoices):
"""
Supported statements
"""
capital_lease_obligations = 'capital_lease_obligations'
net_income = 'net_income'
price = 'price'
total_assets = 'total_assets'
short_term_debt = 'short_term_debt'
total_long_term_debt = 'total_long_term_debt'
total_revenue = 'total_revenue'
total_shareholder_equity = 'total_shareholder_equity'
class TickerStatement(TimeStampMixin):
"""
Model that represents ticker financial statements
"""
name = models.CharField(choices=Statements.choices, max_length=50)
fiscal_date_ending = models.DateField()
value = models.DecimalField(max_digits=MAX_DIGITS, decimal_places=DECIMAL_PLACES)
ticker = models.ForeignKey(Ticker, on_delete=models.CASCADE, null=False,
related_name='ticker_statements')
And now I'm trying to calculate a multiplier. The formula looks like:
(short_term_debt + total_long_term_debt) / total_shareholder_equity
I wrote a raw SQL query
SELECT "fin_tickerstatement"."fiscal_date_ending",
t2.equity AS "equity",
value AS "debt",
short_term_debt AS "short_term_debt",
(value + short_term_debt) / t2.equity AS "result"
FROM "fin_tickerstatement"
JOIN
(SELECT "fin_tickerstatement"."fiscal_date_ending",
fin_tickerstatement.value AS "equity"
FROM "fin_tickerstatement"
WHERE ("fin_tickerstatement"."ticker_id" = 12
AND "fin_tickerstatement"."fiscal_date_ending" >= date'2015-09-03'
AND "fin_tickerstatement"."name" = 'total_shareholder_equity')
GROUP BY "fin_tickerstatement"."fiscal_date_ending",
fin_tickerstatement.value
ORDER BY "fin_tickerstatement"."fiscal_date_ending" DESC) t2
ON fin_tickerstatement.fiscal_date_ending = t2.fiscal_date_ending
JOIN
(SELECT "fin_tickerstatement"."fiscal_date_ending",
fin_tickerstatement.value AS "short_term_debt"
FROM "fin_tickerstatement"
WHERE ("fin_tickerstatement"."ticker_id" = 12
AND "fin_tickerstatement"."fiscal_date_ending" >= date'2015-09-03'
AND "fin_tickerstatement"."name" = 'short_term_debt')
GROUP BY "fin_tickerstatement"."fiscal_date_ending",
fin_tickerstatement.value
ORDER BY "fin_tickerstatement"."fiscal_date_ending" DESC) t3
ON fin_tickerstatement.fiscal_date_ending = t3.fiscal_date_ending
WHERE ("fin_tickerstatement"."ticker_id" = 12
AND "fin_tickerstatement"."fiscal_date_ending" >= date'2015-09-03'
AND "fin_tickerstatement"."name" = 'total_long_term_debt')
GROUP BY "fin_tickerstatement"."fiscal_date_ending",
equity,
debt,
short_term_debt
ORDER BY "fin_tickerstatement"."fiscal_date_ending" DESC;
and have no idea how to translate it into Django ORM. Maybe you have some ideas or know some Django plugins that can help me.
The only way to solve this problem is to install django-query-builder.
How to make the query take correct date from start date and end end of the day for FilterSet.
Now if you type start_filter_date = 2018.05.23 and end_filter_date = 2018.05.25. Then start_filter_date=2018.05.23T00:00 and end_filter_date=2018.05.25T00:00. Time is taken 00:00, but need to be 23:59?
My class is following:
class TaskFilterSet(django_filters.rest_framework.FilterSet):
id = django_filters.NumberFilter(name="pk")
start_filter_date = django_filters.DateFilter(name="date_added", lookup_expr="gte")
end_filter_date = django_filters.DateFilter(name="date_added", lookup_expr="lte")
i think the best way is use gte with lt but send end date date_added + timedelta(1), i don't use the django filters but based on the tips.html#solution-1-magic-values you can try:
class EndFilter(django_filters.DateFilter):
def filter(self, qs, value):
if value:
value = value + timdelta(1)
return super(EndFilter, self).filter(qs, value)
class TaskFilterSet(django_filters.rest_framework.FilterSet):
id = django_filters.NumberFilter(name="pk")
start_filter_date = django_filters.DateFilter(name="date_added", lookup_expr="gte")
end_filter_date = EndFilter(name="date_added", lookup_expr="lt")
I did the code for insert records from so_parts table to so_bo table using Query...How can I use ORM method to do this kind of job. Is there any other way(best)to do that? Here is my code`
`
#api.multi
def save_rapair_parts(self, vals):
#get todays date and convert it to string
created_date = datetime.datetime.today().strftime("%m/%d/%Y")
str_date = str(created_date)
so_p_id = self.so_p_id.id
bo_status = self.bo_status
so_part_t = self.so_part_t
so_part_sno = self.so_part_sno
product = self.so_part_product
product_str = 'Repair '+str(product)
part_id = self.id
bench_order_table.search(['id','bo_sno','created_date','bo_number','rep_description','bo_status'])
#insert details intoso bench orders
`
if so_part_t=='r_b':
try:
sequence = self.env['ir.sequence'].next_by_code('so.benchorder') or '/'
str_sequence = str(sequence)
query = """SELECT so_work_authorization FROM my_depots_so WHERE id=%d """ % (so_p_id)
self.env.cr.execute(query)
result = self.env.cr.fetchall()
result_number = json.dumps(result, ensure_ascii=False)
strip_number = result_number.strip('\' \" [] ')
work_auth_no = str(strip_number)
work_auth_no += "-"
work_auth_no += str_sequence
insert ="""INSERT INTO my_depots_so_bo(id,so_bo_id,bo_sno,created_date,bo_number,rep_description,bo_status) values %s """
parameters = (part_id,so_p_id,so_part_sno,str_date,work_auth_no,product_str,bo_status)
self.env.cr.execute(insert,(parameters,))
my_depots_bo(id,bo_sno,created_date,bo_number,rep_description,bo_status) values %s """
# self.env.cr.execute(insert_query, (parameters,))
except Exception:
print "Error in inserting values"`
yes there is a better way because when you use ORM
method you also checks access right for user to:
for your select query:
rec = self.env['my.depots.so'].search_read(['id', '=', so_p_id], ['so_work_authorization'])
if rec:
rec = rec[0] # search_read return a list of dictionary
so_work_authorization = rec['so_work_authorization']
# and do what ever you want with the result
# to create
# call create method witch accept a dictionary
# field_name : value
new_rec = self.env['my.depots.so.bo'].create({
'so_bo_id': so_p_id, # many2one must be an integer value
'bo_sno': bo_nso_value,
'bo_number': value_of_number,
# ....
# ....
# add al field
}) # create return the new created record as model object
for inserting use: self.env['model.name'].create(vals)
for updating use : self.env['model.name'].write(vals)
using ORM method makes sure that user don't pass the security access rigths
Hope you get the idea