Django Validate M2M Form Save - django

I am trying to creating cron application my model look like :
class Crontab(models.Model):
#Some filelds
...
...
#m2m fields From here prob starts
minute = models.ManyToManyField(Mst_Cron_Minute, db_table="crontab_minute_map")
hour = models.ManyToManyField(Mst_Cron_Hour, db_table = "crontab_hour_map")
day_of_month = models.ManyToManyField(Mst_Cron_Day_Of_Month, db_table="crontab_day_of_month_map")
month = models.ManyToManyField(Mst_Cron_Month, db_table="crontab_month_map")
day_of_week = models.ManyToManyField(Mst_Cron_Day_Of_Week, db_table="crontab_day_of_week_map")
description = models.CharField(max_length=250, blank=True)
is_active = models.IntegerField(choices=YES_NO_CHOICES)
reason_for_deactivate = models.CharField(max_length=250, blank=True)
I need to validate the cron before it saves it into database.
Should not have duplicate cron data saved on this model.
if already a data in db say 5 1 * * * then for new record in the position of * none of the value allowed.
Example 5 1 * * 1 or 5 1 * 1 * or 5 1 1 1 1 not allowed.
if i have a data data 5 1 * 1 * is in DB the new data * 1 * 1 * or 5 * * 1 * ... not allowed, it mean if there is a digit in the position the * not allowed.
How can i validate this ? where my code should go ? Please help me .

Related

Get 1,2,3,4,5 star average individually (1star% +2star% +3star% +4star% +5star%=100%)

Suppose i have rated a user with 1 star 3 times, 2star 1times, 4star 4 times, 5star 10times.now from here anyone can find out overall average rating but how can i get the percentage of 1star,2star ,3star,4star and 5star from total rating
#show it on a django way
rating = Rating.objects.filter(activity__creator=u)
one_star_count = rating.filter(star='1').count()
two_star_count = rating.filter(star='2').count()
three_star_count = rating.filter(star='3').count()
four_star_count = rating.filter(star='4').count()
five_star_count = rating.filter(star='5').count()
total_stars_count = one_star_count + two_star_count+ \
three_star_count + four_star_count+ five_star_count
Create in your User model methods, that count the precentage and then simply use it as needed:
class User(...):
...
def count_star_precentage(self, star):
return (Rating.objects.filter(activity__creator=self, star=star).count() / self.all_ratings().count()) * 100
def all_ratings(self):
return Rating.objects.filter(activity__creator=self)
With them you can get precentage with simple call:
user = User.objects.get(id=some_id)
user.count_star_precentage(3) # it will give the percent of total ratings with 3 star given by that user

Django ORM. Joining subquery on condition

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.

Add Multiple specific time in crontab by python programming

I want to add multiple time( at hour like 12,13,14) in crontab using python2.7.8. How can I do that .
for job in cron.find_comment(cron_id):
job.hour.on(int ('5'))
job.minute.on(int ('30'))
"""It displaying
"30 5 * * * '/export/home/www/current/abc.sh' # IMPORT_TUD
"
"""
#And I am trying to do like....
for job in cron.find_comment(cron_id):
job.hour.on(int ('5,6,7'))
job.minute.on(int ('30'))
"""Output should be like this..
"30 5,6,7 * * * '/export/home/www/current/abc.sh' # IMPORT_TUD
"
But It's not working """
This is code working for single hour entry.... Its working fine but now I have
time like this ['13:00:00','14:00:00','15:00:00']
if daily_job > 0:
sched_str = sched_str.replace(r'",', r",") # this replaces ", with ;
sched_str = sched_str.replace(r'"', '')
time_str = sched_str.split(':')
for job in cron.find_comment(cron_id):
job.hour.on(int(time_str[0]))
job.minute.on(int(time_str[1]))
I found two approach:
1. If we want No. times = No. of cronTab entry like...
30 3 * * * '/etc/crontab/abc.sh' # hello
30 4 * * * '/etc/crontab/abc.sh' # hello
30 5 * * * '/etc/crontab/abc.sh' # hello
file_cron.remove_all(comment='hello')
for i in sched_str:
time_str = i.split(':')
cur_hour = int (time_str[0])
cur_minute = int (time_str[1])
cron_job = file_cron.new('/etc/crontab', comment='hello')
cron_job.hour.on(cur_hour)
cron_job.minute.on(cur_minute)
file_cron.write()
2. For single line of cronTab like (30 3,4,5,6 * * *'/etc/crontab/abc.sh' # hello)
file_cron = CronTab(tabfile='filename.tab')
sched_hour = ['11','13','15']
def one():
cron_job.hour.on(sched_hour[0])
def two():
cron_job.hour.on(sched_hour[0],sched_hour[1])
def three():
cron_job.hour.on(sched_hour[0],sched_hour[1],sched_hour[2])
options = {1: one,
2: two,
3: three,
}
a = len(sched_hour)
for cron_job in file_cron.find_comment('hello'):
options[a]()
cron_job.minute.on(40)
file_cron.write()

Select values from two tables using Django

I have two tables as follows,
cabinet
cabinet_id cabinet_name
1 Test1
2 Test2
3 Test3
cabinet_maping
id product_id cabinet_id size
1 34 1 20
2 34 3 25
How can I select all cabinet_name from cabinet table where cabinet_maping.product_id = 34 in Django
Expected Output as follows,
cabinet_id cabinet_name size
1 Test1 20
2 Test2 0
3 Test3 25
I think that yours models could look like
class Cabinet(models.Model):
name = models.CharField(max_length = 30)
class cabinet_maping(models.Model):
product = models.ForeignKey(Product)
cabinet = models.ForeignKey(Cabinet)
size = .....
You should do sth like this:
cabinet_name = cabinet_maping.objects.filter(product__id = 34)
for item in cabinet_name:
print item.cabinet.id
print item.cabinet.name
print item.size
I didn't check it but i think that should work (that works :))
I agree with Silwestpl that your models are wrong as using Foreign Key would make this query a lot easier. But just an answer to your question would be. I am assuming that you dont have any relationships between the two tables as you haven't mentioned any.
x = Cabinet_mapping.objects.filter(product_id = somevalue).distinct('cabinet_id')
response_list = []
for y in x:
response_dict = {}
response_dict['cabinet_id'] = y.cabinet_id
response_dict['cabinet_name'] = cabinet.objects.get(id = y.cabinet_id).cabinet_name
response_dict['size'] = y.size
response_list.append(response_dict)
return response_list
This would be the answer according to the details you have provided.
But Ideally I would do something like this
class Product(models.Model):
# id is generated automatically.
## any other fields that you want for product.
class Cabinet(models.Model):
# again id is auto-genearated.
cabinet_name = models.CharField(max_length=100)
cabinet_size = models.IntegerField()
products = models.ManytoManyField(Product)#This automatically maps product_id n cabinet_id.
And your query would be.
x = Cabinet.objects.filter(product.id=some_value)
print (x.id , x.cabinet_name, x.cabinet_size) # I used print, but you can use it anyway you want.
This would be what you require. Please use the second solution if you are looking into something serious.

Django - Add online columns in "select"

I dont know if this is the best way to resolve my problem, if isn't , tell me plz :)
I have this model :
class userTrophy(models.Model):
user = models.ForeignKey(userInfo)
platinum = models.IntegerField()
gold = models.IntegerField()
silver = models.IntegerField()
bronze = models.IntegerField()
level = models.IntegerField()
perc_level = models.IntegerField()
date_update = models.DateField(default=datetime.now, blank=True)
Now i want to retrieve one user info, but i want add 3 new "columns" online :
total = platinum + gold + silver + bronze
point = platinum * 100 + gold * 50 + silver * 25 + bronze * 10
and sort by "point", after sort, put a new column, with a sequencial number: rank (1-n).
Can i do this ( or part of this ) working only with the model ?
I am sure there are many ways to achieve this behavior. The one I am thinking of right now is a Custom Model Manager and transient model fields.
Your class could look like so:
from django.db import models
from datetime import datetime
class UserTrophyManager(models.Manager):
def get_query_set(self):
query_set = super(UserTrophyManager, self).get_query_set()
for ut in query_set:
ut.total = ut.platinum + ut.gold + ut.silver + ut.bronze
ut.points = ut.platinum * 100 + ut.gold * 50 + ut.silver * 25 + ut.bronze * 10
return query_set
class UserTrophy(models.Model):
user = models.CharField(max_length=30)
platinum = models.IntegerField()
gold = models.IntegerField()
silver = models.IntegerField()
bronze = models.IntegerField()
level = models.IntegerField()
perc_level = models.IntegerField()
date_update = models.DateField(default=datetime.now, blank=True)
total = 0
point = 0
objects = UserTrophyManager()
class Meta:
ordering = ['points']
So you can use the following and get total and point calculated:
user_trophies = userTrophy.objects.all()
for user_trophy in user_trophies:
print user_trophy.total
Here's the way I would do it. Add the columns 'total' and 'points' to your model, like this:
class UserTrophy(models.Model):
...
total = models.IntegerField()
points = models.IntegerField()
...
Override the save method for your model:
def save(self, *args, **kwargs):
# Compute the total and points before saving
self.total = self.platinum + self.gold + self.silver + self.bronze
self.points = self.platinum * 100 + self.gold * 50 + \
self.silver * 25 + self.bronze * 10
# Now save the object by calling the super class
super(UserTrophy, self).save(*args, **kwargs)
With total and points as first class citizens on your model, your concept of "rank" becomes just a matter of ordering and slicing the UserTrophy objects.
top_ten = UserTrophy.objects.order_by('-points')[:10]
You'll also want to make sure you have your fields indexed, so your queries are efficient.
If you don't like the idea of putting these fields in your model, you might be able to use the extra feature of Django query set objects to compute your total and points on the fly. I don't use this very often, so maybe someone else can put together an example.
Also, I recommend for you to read PEP 8 for Python coding conventions.
This is more of a followup question than an answer, but is it possible to do something like:
class userTrophy(models.Model):
... stuff...
def points(self):
self.gold + self.silver + self.bronze
then call something like object.points in a template. Im just curious if that is a possibility