Datepicker range Plotly-Dash - Make user unable to include disabled dates in the date range - plotly-dash

I am using the datepickerrange component in plotly dash, and i am trying to make it so that whenever a starting date is selected, it will not be possible to include a disabled date inside the interval.
Example: i select the 5th of may as starting date. Since i have disabled the 10th of may, it should only be possible to select 5th of may - 9th of may in order to avoid a disabled date inside the date interval.
In this example i need to change the max_date_allowed to be the 9th of may, and the min_date_allowed to be the 5th of may after selecting the 5th as starting date.
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
disabled_days = ['2022-05-10']
app = Dash(__name__)
app.layout = html.Div([
dcc.DatePickerRange(
id='my-date-picker-range',
minimum_nights=2,
number_of_months_shown=2,
clearable=True,
disabled_days=disabled_days,
),
])
#app.callback(
Output('my-date-picker-range', 'max_date_allowed'),
Output('my-date-picker-range', 'min_date_allowed'),
Input('my-date-picker-range', 'start_date'))
def update_output(start_date):
if start_date is not None:
return '2022-05-09', '2022-05-05'
else:
raise PreventUpdate
if __name__ == '__main__':
app.run_server(debug=True)
In this script, dates outside min-max date are not clickable and do not show a hover colour, however, the CSS appearance of the numbers do not turn grey. I would like to fix it such that the dates are both disabled physically, and their appereance are also changed.

Related

Django: empty date string should return all

So, I have a date from input field, and date to input field. When I pass in the date range from and to it works fine. But when I try to leave one or both blank, to get all the items, or partial items, it gives ValueError: Cannot use None as a query value or format error when I try to make the default empty string.
def report(self, request):
date_from = query['date_from'] if query['date_from'] else None
date_to = query['date_to'] if query['date_to'] else None
queryset = Client.objects.filter(
client_code__in=clients,
account__note__creation_time__gte=date_from,
account__note__creation_time__lte=date_to,
)
To give a better context, if I leave both field empty i should get all items from beginning to now, if I fill in date from field but leave date to field empty, I should get all item from date from till now. If I have date to field buy empty date from field, I should get items from beginning till date to.
Got lazy and found a solution that works but not very happy with it. If someone finds something better feel free to share.
query = Q()
if clients:
clients = clients.split(',')
query &= Q(client_code__in=clients)
if date_from:
query &= Q(account__note__creation_time__gte=date_from)
if date_to:
query &= Q(account__note__creation_time__lte=date_to)
Client.objects.filter(query)
If you put a filter on the queryset you have to supply valid values for that filter.. Django can't guess that you actually don't want the filter after all...
But there are ways to make it a little nicer looking, eg:
qs = Client.objects.all()
if date_from:
qs = qs.filter(account__note__creation_time__gte=date_from)
if date_to:
qs = qs.filter(account__note__creation_time__lte=date_to)
# etc etc for all your AND queries.
# but for OR type queries you need to use Q objects.
When you create a queryset, as I did using Client.objects.all, it doesn't actually go to the database and get the objects right away. So you can then modify that queryset by adding additional filters onto it to limit your results. You can use all the different queryset methods.. eg order_by(), fetch_related() etc.. until the queryset is how you want it. It won't actually execute any SQL until you try to read the objects by iterating over the queryset, eg:
# now it will go to the database and get the objects based on your filters.
for instance in qs:
print instance
So you see, in this case, where all your filters are narrowing the search (they are all AND'ed together), there's no need to use Q() and that makes for less typing and clearer code. But if you are doing a query where you are using OR logic or where you are perhaps applying the same query to multiple querysets, then you do need to use the Q class to form that query.

Datetime input for current or future time

The default value of the form input should be the current time. The user should can select to provide a time in the future and than a normal datetime field should be shown. Can this be realized without javascript and how?
You can leave the input empty and change it to the current time on the backend (or maybe set it to the current time at the moment of rendering template and interpret past times as "now"). But the most you can do without JavaScript is adding a comment that empty input means current time. If you want to make some kind of fancy checkbox for current time and maybe hide the datetime input, you should do it with JavaScript
You can try to use <input name="date_input" type="date" id="date_input"> in your template.
And do views do :
from datetime import datetime
# get a string from a POST like "10/2/2018"
date_get = request.POST.get("date_input")
# format of date/time strings; assuming dd/mm/yyyy
date_format = "%d/%m/%Y"
# create datetime objects from the strings
date = datetime.strptime(date_get, date_format)
# Check if we have a datetime
print(date)
datetime.datetime(2018, 2, 10, 0, 0)

Trying to import %m/%d into Rails where no %Y is available in the csv

I have a csv with only the month and date, like this: 08/22, and can't import it into my Rails 4 app. It just gets ignored. I've tried:
:birthday =>DateTime.strptime("%m/%d").strftime("%m/%d")
converters: [:date]
and a few other things. Is is at all possible to bring a date that has no year into a Rails database?
if you are the one performing the imports / building the spread sheet, you could format the date field in the excel sheet to a random year, then upload the form with the dummy year but then use strftime in your index, show pages ect to only display the date and month. if year is not important i dont see why this wouldnt work.
I have used this method in the past where my client provided data did not have years attached and it worked for me.
hope this helps.

How to retrieve records from past weeks in django

I am having trouble in django on how to retrieve data from last week (not 7 days ago). Using date.isocalendar()[1] would be great. However Some stackoverflow browsing lead me to no satisfactory results.
Whatsoever, I could do without portability and use mysql's INTERVAL function. This is the query I want to make using django's ORM.
SELECT id, user_id, CAST(timestamp AS Date), WEEK(timestamp,3), WEEK(CURDATE(), 3) FROM main_userstats WHERE week(timestamp, 3) = WEEK(DATE_SUB(CURDATE(), INTERVAL 1 WEEK ), 3)
how can I do this using the extra function in django (if it's not possible to do in any other simpler way)?
I assume what you are looking for are all the entries that belong to the same calendar week of the previous week.
This should do the trick:
class Entry(models.Model):
pub_date = models.DateField([...])
To get the objects:
from datetime import timedelta
from django.utils import timezone
some_day_last_week = timezone.now().date() - timedelta(days=7)
monday_of_last_week = some_day_last_week - timedelta(days=(some_day_last_week.isocalendar()[2] - 1))
monday_of_this_week = monday_of_last_week + timedelta(days=7)
Entry.objects.filter(created_at__gte=monday_of_last_week, created_at__lt=monday_of_this_week)
Note that I added 7 days to get the monday of the this week instead of adding 6 days to get the sunday of last week and that I used created_at__lt=monday_of_this_week (instead of __lte=). I did that because if your pub_date was a DateTimeField, it wouldn't include the sunday objects since the time is 00:00:00 when using now().date().
This could easily be adjusted to consider Sunday as the first day of the week instead, but isocalendar() considers it the last, so I went with that.
If using Django < 1.4 use the following:
from datetime import date, timedelta
some_day_last_week = date.today() - timedelta(days=7)
instead of:
from datetime import timedelta
from django.utils import timezone
some_day_last_week = timezone.now().date() - timedelta(days=7)
Look at the the filter method of Django ORM.
Basic example:
class Entry(models.Model):
pub_date = models.DateField([...])
Entry.objects.filter(pub_date__year=2006)
But you can do more complex queries with filter like:
Entry.objects.filter(pub_date__gte=datetime.now())
As you can see, you can use datetime and other python libraries to define specific dates. Look at the documentation for field lookups to see which posibilities you have.
In your case you could do something like this (inspired by this Stackoverflow post):
from datetime import date, timedelta
d=date.today()-timedelta(days=7)
Entry.objects.filter(pub_date__gte=d)
I'm not a 100% sure if this lookup will work, but it is the right direction.
You can query the data by week number week and iso_year
import datetime
date = datetime.datetime.today()
week = date.strftime("%V")
Entry.objects.filter(pub_date__week=week)
from django.utils.the timezone import now
year, week, _ = now().isocalendar()
Entry.objects.filter(pub_date__iso_year=year, pub_date__week=week)

How to set up GUI date input to retain format look and feel

Okay I've tried this a few different ways and haven't been able to get it to do what I want it to. I've also visited this page: http://www.exampledepot.com/egs/javax.swing.text/formtext_FormTextDate.html
I have a spinner:
SimpleDateFormat datePattern = new SimpleDateFormat("MM/dd/yyyy");
JLabel endLabel = new JLabel("End Date: ");
JSpinner endSpinner = new JSpinner(new SpinnerDateModel());
endSpinner.setEditor(new JSpinner.DateEditor(endSpinner, datePattern.toPattern()));
This automatically loads today's date. I would prefer it to just show MM/DD/YYYY within the actual gui. This would give it the look of being date input without requiring a specific date to be entered if not required. Then as soon as you start spinning it would take a date. I can't seem to figure out how to do this. Any suggestions? I've also started looking up FormattedTextFields as well as an option. Would this be a better route to go?
If so, how can I set up the FormattedTextField to look like this: [ / / ]. Then when you put input in, keep that format, requiring only digits and 2 digits for month, 2 digits for day, and 4 digits for year. I would assume I'd have to set up some sort of pattern instead of initializing the FormattedTextField as a date? For example:
JFormattedTextField date = new JFormattedTextField(new SimpleDateFormat("MM/dd/yyyy"));
date.setValue(" / / ");
But all you would have to do is clear out the field and it would no longer look like a date. I want it to at least keep the '/' no matter what you do.
Sorry for the long drawn out question.