I would like to get rows from specified date range, but when limiter is None (beg_date==None, fin_date==None) I want to ignore scope on one side.
For instance:
If beg_date=='2019-10-23' and fin_date==None I would like to get
rows from 2019-10-23 up to date.
How can I achieve that using SQLAlchemy?
Model:
class MyModel(Model):
date = Column(Date)
Code:
beg_date = some_dict.get('beg_date')
fin_date = some_dict.get('fin_date')
session.query(MyModel).filter(MyModel.date.between(beg_date, find_date)
You could build your date condition with Python conditions on start_date and end_date before building your whole query:
if start_date and end_date:
date_condition = MyModel.date.between(start_date, end_date)
elif start_date:
date_condition = MyModel.date > start_date
elif end_date:
date_condition = MyModel.date < end_date
else:
date_condition = true() # sqlalchemy.true()
session.query(MyModel).filter(date_condition)
I did not tested it but it should work with potential minor fixes.
Related
What i'm trying to do is to add one extra day to today's date and have the outcome match this formula "%Y-%m-%d" and nothing else. I want the printed results to match this yyyy-mm-dd
from datetime import datetime, timedelta, date
s = date.today()
date = datetime.strptime(s, "%Y-%m-%d")
modified_date = date + timedelta(days=1)
datetime.strftime(modified_date, "%Y-%m-%d")
print(modified_date)
You are trying to do date operations on strings and not using the result of your formatting call:
s = date.today()
modified_date = s + timedelta(days=1)
modified_date = modified_date.strftime("%Y-%m-%d") # this would be more common
# modified_date = datetime.strftime(modified_date, "%Y-%m-%d")
print(modified_date)
I am trying to build a condition where the store has a s_start_date and s_end_date.
The employee working for the store also has a start_date and end_date.
Let's assume:
Case1------------
store_name: store 1
s_start_date = 12/01/2019, s_end_date = 12/30/2019
Employee_name: Emp1
start_date = 12/01/2019, end_date = 12/20/2019 #Required result
start_date = 11/01/2019, end_date = 01/20/2020 #It should throw an error as the dates are out of store contract.
case 2-----------------
The condition here is that only one employee is needed at a single store
store_name: store 1
s_start_date = 12/01/2019, s_end_date = 12/30/2019
Employee_name: Emp1
start_date = 12/01/2019, end_date = 12/20/2019 #Required result
Employee_name: Emp2
start_date = 12/21/2019, end_date = 12/30/2019 #Required result
start_date = 12/05/2019, end_date = 12/17/2019 #Should throw an error saying that employee already exist for the time frame or dates not available
Please find the attached code for your reference .
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class wv_location(models.Model):
_name= "wv.location"
storel_name = fields.Char(string="Store Name")
s_start_date = fields.Date('Store Start Date', required=True, index=True)
s_end_date = fields.Date('Store End Date', constrains="_check_date")
emp_loc_id = fields.One2many('wv.emp.location', 'employee_loc_id', string="Employees")
#api.constrains('s_start_date','s_end_date')
def _check_date(self):
if self.s_start_date > self.s_end_date:
raise ValidationError('End date must be greater than start date')
class wv_emp_location(models.Model):
_name = "wv.emp.location"
employee_id = fields.Many2one('hr.employee', 'Employee', ondelete='cascade')
employee_loc_id = fields.Many2one('wv.location', 'Employee Location', ondelete='cascade')
start_date = fields.Date('Start Date', tracking=True)
end_date = fields.Date('End Date', tracking=True)
#api.constrains('start_date','end_date')
def _check_date(self):
if self.start_date > self.end_date:
raise ValidationError('End date must be greater than start date')
Please let me know if you need more information on this. I know I can use loops and lists but not sure of how to use for these conditions and not sure of logic.
Thank you
I have a Deadline model which have two fields, start_date and end_date.
I want to sort the queryset with both the fields but have a copy of deadline for each date
I tried creating annotated common fields and ordering through that.
class Deadline(models.Model):
start_date = models.DateTimeField()
end_date = models.DateTimeField
dl_start = deadline_queryset.annotate(date=F('start_date'))
dl_end = deadlien_queryset.annotate(date=F('end_date'))
dl_all = dl_start.union(dl_end).order_by('date')
I need a timeline of events.
Consider if my queryset has 2 objects:
Deadline <id: 1, start_date: 12-dec, end_date: 24-jan>
Deadline <id: 2, start_date: 15-dec, end_date: 21-jan>
I need a list of deadlines like:
Deadline <id: 1, start_date: 12-dec, end_date: 24-jan, date: 12-dec>
Deadline <id: 2, start_date: 15-dec, end_date: 21-jan, date: 15-dec>
Deadline <id: 2, start_date: 15-dec, end_date: 21-jan, date: 21-jan>
Deadline <id: 1, start_date: 12-dec, end_date: 24-jan, date: 24-jan>
In my aforementioned code, the annotated fields were not being carry forward after the union and so I was unable to use order_by on it.
It worked after using the following variation:
dl_start = deadline_queryset.annotate(date=F('start_date')).values('id', 'start_date', 'end_date', 'date')
dl_end = deadlien_queryset.annotate(date=F('end_date')).values('id', 'start_date', 'end_date', 'date')
dl_all = dl_start.union(dl_end).order_by('date')
This helped me carry forward the annotated date field.
I have a code :
def set_date_range_filter(self,attribute = None,start_date = None , end_date = None):
if attribute is None:
return
#Make sure set the passing start date and end date
if not start_date or not end_date :
return
if isinstance(start_date, str) :
start_date = datetime.strptime(start_date, "%Y-%m-%d")
if isinstance(start_date, unicode) :
start_date = datetime.strptime(str(start_date), "%Y-%m-%d")
if isinstance(end_date ,str):
end_date = datetime.strptime(end_date, "%Y-%m-%d")
if isinstance(end_date ,unicode):
end_date = datetime.strptime(str(end_date), "%Y-%m-%d")
# Shphnx Range Filter ,start_date and end_date must be integers that define the acceptable attribute values range
start_date = int(time.mktime(start_date.timetuple()))
end_date = int(time.mktime(end_date.timetuple()))
if start_date > end_date :
return
self.sphinx.SetFilterRange(str(attribute),start_date,end_date)
I want to update this code to accept only 'start_date' or only 'end_date' or both.
Like i want all date from 2014-01-01 or i want all data after 2014-01-01
or say i want all data from 2014-01-01 to 2014-09-01. how can i archive this ??
Rather than
if not start_date or not end_date :
return
replace with say
if not start_date:
start_date = '1971-01-01'
if not end_date:
end_date = '2037-01-01'
Or similar. If either are missing, then just use a very early, or very late dates (outside the range of your data). Example dates above choosen within range of unix timestamps.
(will then be turned into proper date objects via strptime)
I need to perform a filter by date with a form where if one of the date parameters is suppressed the upper/lower border of the date range is not being set in filter (which means min possible date/max possible date, respectively)
My code is:
#forms.py
...
start_date = forms.DateField(
required=False,
)
end_date = forms.DateField(
required=False
)
...
# views.py
def get(self, *args, **kwargs):
form = self.request.GET
if form.is_valid():
cd = form.cleaned_data
if not cd['start_date']:
start_date = datetime.date(1,1,1)
else:
start_date = cd['start_date']
if not cd['end_date']:
end_date = datetime.date(3000,1,1)
else:
start_date = cd['end_date']
MyC.objects.filter(date__range=(start_date,end_date))
This code works but looks very cludgy to me (Many senseless if clauses, duplicate code, etc).
Maybe there is a Filter function for this case (if start date is None -> don't filter)?
You can apply the filters as needed. The query won't happen until you use the queryset.
objects = MyC.objects.all()
if cd['start_date']:
objects = objects.filter(date__gt=cd['start_date'])
if cd['end_date']:
objects = objects.filter(date__lt=cd['end_date'])
return objects
if you need default dates you can do:
start_date = self.cleaned_data.get('start_date', datetime.date(1,1,1))
end_date = self.cleaned_data.get('end_date', datetime.date(3000,1,1))
MyC.objects.filter(date__range=(start_date, end_date))