__init__() got multiple values for keyword argument 'input_formats' - python

forms.py
from django import forms
ACCEPTED_FORMATS = ['%d-%m-%Y', '%d.%m.%Y', '%d/%m/%Y']
class LeaveRequestForm(forms.Form):
start_date = forms.DateField(input_formats=ACCEPTED_FORMATS)
end_date = forms.DateField(input_formats=ACCEPTED_FORMATS)
working_days = forms.IntegerField(min_value=1)
I couldn't find any date format that could pass form validation, every time I received 'Enter a valid date.', so when I tried to define some the exception came out:
__init__() got multiple values for keyword argument 'input_formats'
https://docs.djangoproject.com/en/1.8/ref/forms/fields/#datefield
settings.py
...
USE_I18N = True
USE_L10N = True
...
I also tried built-in SelectDateWidget with no luck, every time produced invalid date. Maybe there is some "cache" issue:
"Enter a valid date" Error in Django Forms DateField
What should I do to get past this validation checks and move on with proper dates? Are the docs missing something with an error I encountered?

input_formats is not a kwarg, it's the sole option to DateField. Drop the input_formats=
ACCEPTED_FORMATS = ['%d-%m-%Y', '%d.%m.%Y', '%d/%m/%Y']
class LeaveRequestForm(forms.Form):
start_date = forms.DateField(ACCEPTED_FORMATS)
end_date = forms.DateField(ACCEPTED_FORMATS)
working_days = forms.IntegerField(min_value=1)

Related

How to substract custom date in models.DateField from now()?

I still can't find a working solution, hence I decided to throw my first post. Note, I'm a beginner in Django.
Building a portal that displays days since the user has been verified.
I tested my model without using custom DateField (verified_since), just with date_joined, and it works properly - showing the count of days remaining (I countdown from 365 days, I am not worried about the leap year yet) since the user has registered in the database vs. today.
class Profile(models.Model):
verified_since = models.DateField(default=now)
#property
def ver_since(self):
return 365 - (now() - self.user.date_joined).days
Now if I use verified_since instead date_joined, I get an error. I suspect this is due to a different format of a date, or maybe a string format instead of a date which can't be subtracted then from datetime.now()
verified_since is manually entered date on the form by user.
class Profile(models.Model):
verified_since = models.DateField(default=now)
#property
def ver_since(self):
return 365 - (now() - self.user.verified_since).days
Here is settings:
TIME_ZONE = 'CET'
USE_I18N = True
USE_L10N = False
USE_TZ = True
TIME_INPUT_FORMATS = ('%H:%M',)
DATE_INPUT_FORMATS = ['%d/%m/%Y']
datetime.now() gives you datetime object, while your 'verified_since' is a date field. So just convert your current datetime to date.
>>> verified_since
datetime.date(2022, 4, 8)
>>> datetime.now().date()
datetime.date(2022, 4, 12)
>>> 365 - (datetime.now().date() - verified_since).days
361
PS: I don't know what ver_since is for, but logically speaking, it's definitely not "verified since - in days"

Django can't lookup datetime field. int() argument must be a string, a bytes-like object or a number, not datetime.datetime

I'm trying to group objects 'Event' by their 'due' field, and finally return a dict of day names with a list of events on that day. {'Monday': [SomeEvent, SomeOther]} - that's the idea. However while looking up event's due__day I get: int() argument must be a string, a bytes-like object or a number, not datetime.datetime.
Here's manager's code:
# models.py
class EventManager(models.Manager):
def get_week(self, group_object):
if datetime.datetime.now().time() > datetime.time(16, 0, 0):
day = datetime.date.today() + datetime.timedelta(1)
else:
day = datetime.date.today()
friday = day + datetime.timedelta((4 - day.weekday()) % 7)
events = {}
while day != friday + datetime.timedelta(1):
events[str(day.strftime("%A"))] = self.get_queryset().filter(group=group_object, due__day=day)
# ^^^ That's where the error happens, from what I understood it tries to convert this datetime to int() to be displayed by template
day += datetime.timedelta(1)
return events
Here is the model:
# models.py
class Event(models.Model):
title = models.CharField(max_length=30)
slug = models.SlugField(blank=True)
description = models.TextField()
subject = models.CharField(max_length=20, choices=SUBJECTS)
event_type = models.CharField(max_length=8, choices=EVENT_TYPES)
due = models.DateTimeField()
author = models.ForeignKey(User, blank=True)
group = models.ForeignKey(Group, related_name='events')
objects = EventManager()
I created a template filter to call this method:
#register.filter
def get_week(group_object):
return Event.objects.get_week(group_object=group_object)
And I called it in event_list.html (Using an index because it's a list view, also this is just temporary to see if the returned dict will be correct. Looping over it is to be implemented.)
{{ event_list.0.group|get_week }}
My guess is: I've broken something with this weird lookup. .filter(due__day=day) However I cannot find the solution.
I also tried to look for due__lte=(day - datetime.timedelta(hours=12)), due__gte=(day + datetime.timedelta(hours=12)) something like this but that doesn't work. Any solution is pretty much fine and appreciated.
Right, so the solution for my project is to check for due__day=day(the one from the loop).day <- datetimes property to compare day agains day not day against the datetime. That worked for me, however it does not necessarily answer the question since I don't exactly what caused the error itself. Feel free to answer for the future SO help seekers or just my information :)
This works for me:
Event.objects.filter(due__gte=datetime.date(2016, 8, 29), due__lt=datetime.date(2016, 8, 30))
Note that it uses date instead of datetime to avoid too much extraneous code dealing with the times (which don't seem to matter here).

Python/Django date query: Unsupported lookup 'date' for DateField or join on the field not permitted

I have a simple method. Entries are entries in a time sheet application where employees enter their hours.
class Entry(m.Model):
""" Represents an entry in a time_sheet. An entry is either for work, sick leave or holiday. """
# type choices
WORK = 'w'
SICK = 's'
VACATION = 'v'
type_choices = (
(WORK, 'work'),
(SICK, 'sick leave'),
(VACATION, 'vacation'),
)
# meta
cr_date = m.DateTimeField(auto_now_add=True, editable=False, verbose_name='Date of Creation') # date of creation
owner = m.ForeignKey(User, editable=False, on_delete=m.PROTECT)
# content
type = m.CharField(max_length=1, choices=type_choices, default='w')
day = m.DateField(default=now)
start = m.TimeField(blank=True) # starting time
end = m.TimeField(blank=True) # ending time
recess = m.IntegerField() # recess time in minutes
project = m.ForeignKey(Project, on_delete=m.PROTECT)
#classmethod
def get_entries_for_day(cls, user, day):
""" Retrieves any entries for the supplied day. """
return Entry.objects.filter(day__date=day, owner=user).order_by('start')
However, when I try to run my project like this, it terminates with the following error code:
"Unsupported lookup 'date' for DateField or join on the field not
permitted."
I don't quite understand the message. The specified field is a date field which has no further restrictions. Any hints would be appreciated.
There's no such thing as a __date lookup on a DateField; the field is already a date.
It's not clear what you are trying to compare this field with. Is the day you are passing into that method an integer, or a date? If it's also a date then you should just compare them directly.
I'm facing an issue with Django-filters, The filter was not taking the same date range while I was using it. so I added date__lte/gte in lookup_expr.something like this.
from_date = django_filters.DateFilter(field_name="created_at", lookup_expr='date__gte')
to_date = django_filters.DateFilter(field_name="created_at", lookup_expr='date__lte')

Django count grouping by year/month without extra

I'm working with django 1.9
Model :
class Comment(models.Model):
title = models.CharField(max_length=250, null=False)
date = models.DateField(auto_now_add=True)
As 'extra()' will be deprecated in django i try to figure out how to count Comments group by year-month without using 'extra'
Here is the code with extra :
Comment.objects.extra(select={'year': "EXTRACT(year FROM date)",
'month': "EXTRACT(month from date)"})\
.values('year', 'month').annotate(Count('pk'))
Thank you for your help.
See year and month in the docs, may be something like the following will do the job:
Comment.objects.annotate(year=Q(date__year),
month=Q(date__month)
).values('year', 'month').annotate(Count('pk'))
If this won't work, then instead of Q(date__year), you could define a custom Func() expression representing EXTRACT(year FROM date) function and use it in annotate(). Or, well, as last resort there's RawSQL().
Using Func(), something like this:
from django.db.models import Func
class Extract(Func):
"""
Performs extraction of `what_to_extract` from `*expressions`.
Arguments:
*expressions (string): Only single value is supported, should be field name to
extract from.
what_to_extract (string): Extraction specificator.
Returns:
class: Func() expression class, representing 'EXTRACT(`what_to_extract` FROM `*expressions`)'.
"""
function = 'EXTRACT'
template = '%(function)s(%(what_to_extract)s FROM %(expressions)s)'
#Usage
Comment.objects.annotate(year=Extract(date, what_to_extract='year'),
month=Extract(date, what_to_extract='month')
).values('year', 'month').annotate(Count('pk'))

Django URL error

Error:
Reverse for 'charges_report' with arguments '(u'rtcl', datetime.date(2012, 1, 3), datetime.date(2012, 1, 4), u'')' and keyword arguments '{}' not found.
in my urls.py
url(r'^charges_report/(?P<company_name>[\s\w\d-]+)/(?P<start_date>[\s\w\d-]+) /(?P<close_date>[\s\w\d-]+)/(?P<batch_no>[\s\w\d-]+)/$',
'admin.reports.views.charges_report',
name='charges_report'),
and in my form views on POST
When user submits form the error is occurring. I mean on request.POST, Here is the code for form submit
if request.POST:
company_form = CompanyForm(request.POST, request=request)
if company_form.is_valid():
company_name = company_form.cleaned_data['company_name']
start_date = company_form.cleaned_data['start_date']
close_date = company_form.cleaned_data['close_date']
batch_no = company_form.cleaned_data['batch_no']
#if 'immigration_charges' in request.POST:
return HttpResponseRedirect(reverse('charges_report',args=[company_name, start_date, close_date, batch_no]))
in views
def charges_report(request, company_name, start_date, close_date, batch_no=None,):
Your URL is taking keyword arguments, but you are passing positional arguments in reverse.
Try:
kwargs = dict()
kwargs['company_name'] = company_name
kwargs['start_date'] = start_date
kwargs['close_date'] = close_date
kwargs['batch_no'] = batch_no
return HttpResponse(reverse('charges_report',kwargs=kwargs))
You also need to format your dates to match the regular expression in your URL pattern. Right now you are passing the literal string datetime.date(2012, 1, 3) as the start_date.
Change start_date (and close_date) to something that matches your regular expression, something like this:
kwargs['start_date'] = "{}".format(start_date)
kwargs['close_date'] = "{}".format(close_date)
The Django URL dispatch documentation cautions that:
"If there are any errors whilst importing any of your view functions, it will cause reverse() to raise an error, even if that view function is not the one you are trying to reverse."
"Make sure that any views you reference in your URLconf files exist and can be imported correctly."
"Do not include lines that reference views you haven't written yet." -
One of these may be your problem.
Try using a kwarg dictionary instead of positional arguments.

Categories