date-format not working on html page with datepicker - django

First, I'm relatively new to Django. I've seen my question addressed here with answers that I've tried to implement without success. Using a date picker that formats the date differently then how its stored and returned on the form initially.
forms.py
....
start_date = forms.Datefield(widget=forms.DateInput(format='%m/%d/%Y'), input_formats=['%m/%d/%Y'])
queries.html
....
<div class="col-4">
<label for="start_date" style="font-weight: bold;">Start Date</label>
<div class="input-group date" data-provide="datepicker">
<input type="text" name="start_date" id="start_date" value="{{queryform.start_date.value}}" class="form-control">
<div class="input-group-addon"><span class="glyphicon glyphicon-th"></span></div>
</div>
</div>
....
<form method="post">
{% csrf_token %}
<script>
$(function() {
$( ".datepicker" ).datepicker({
changeMonth: true,
dateFormat: 'mm/dd/yyyy',
changeYear: true,
yearRange: "2010:2025"
});
});
</script>
url.py
path('editqueries/<id>', views.editqueries, name='editqueries'),
views.py
def editqueries(request, id):
query_data = get_object_or_404(Query, pk=id)
if request.method == "POST":
query_form = QueryForm(request.POST, instance=query_data)
if query_form.is_valid():
the_query_name = query_form.cleaned_data["query_name"]
# get the hidden field from the html page (but not on the
# Django form)
current_query_name = request.POST["currentqueryname"]
# test to be sure if the names are not the same that changing
# the name doesn't create a duplicate query_name
if not the_query_name == current_query_name:
try:
test_query =
Query.objects.get(query_name=the_query_name)
except Query.DoesNotExist:
# this is allowed. Named changed does not create a
# duplicate
query_form.save()
query = Query.objects.all()
query_flag = "None"
context = {'queries': query, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html',
context)
# successful query means this name is in use.
# Stop the renaming of the query.
return HttpResponse("ERROR: Query Name '" +
the_query_name + "' Already exist!")
query_form.save()
query = Query.objects.all()
query_flag = "None"
context = {'queries': query, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html', context)
else:
return HttpResponse("Form is invalid.. errors:" +
str(query_form.errors))
else:
query_form = QueryForm(instance=query_data)
# tell the user the query is ready to be updated.
query_flag = "Edit"
context = {'queryform': query_form, 'query_flag': query_flag}
return render(request, 'seakerUI/queries.html', context)
queries.html
see code above
So when attempting to edit a query, the page is formatted with the date like "Aug. 2, 2019". However, if one submits the form without changing the date, the form is invalid and the form.error is date is invalid.
I've set the following line in settings.py
DATE_INPUT_FORMATS = ['%m/%d/$Y']
I've had 2 other formats in this definition but none seem to work.
I also executed
python manage.py diffsettings
and though it shows in the output the impact is negligible.
I've attempted using many examples of structuring the forms.py file using a widget function and without it without success. The problem does not appear to be with the javascript on the hmtl page.
NOTE: If I change the date when the edit query page presents it then the form validates. However, if one doesn't change the date and the form is submitted it is not valid and an error occurs. I shouldn't have to change the date to get the form to validate.
Suggestions?

You can try with html5 and WTF forms.
Html5 and WTFforms together can be used to select and date/month/year and process.
In form.py:
from wtforms.fields.html5 import DateField
Accept the inputs as shown :
dob= DateField('Password - Your Date of Birth', validators=[DataRequired()], format='%Y-%m-%d')
In html
form.dob(class="form-control form-control-lg")

Related

Django Search functionality: form returns None

i am trying to build a django search functionality for my app but the input form keeps returning a none
views.py
def search(request):
if request.method == 'POST':
query = request.POST.get('text')
houses = Product.objects.filter(name__contains='query')
context = {
'houses':houses,
}
return render (request, 'searchresult.html', context)
search.html
<form>
<input type='text' placeholder='search houses>
<button type='submit'>Search</button>
</form>
First off, your python indentation is invalid, and your HTML is also invalid on the input line. I will assume this is a typo in the question, but if not, you have issues there.
Your main problem is the filter for houses:
houses = Product.objects.filter(name__contains='query')
is looking for a name containing the string "query". You need the variable you've just defined.
houses = Product.objects.filter(name__contains=query)
You have an indentation issue in the code you have posted.
You need to add action and method in your Form.
<form action="/url_of_search/" method="post">
Missing quote in input line.
<input type='text' placeholder='search houses'>
You need to use query instead of 'query' in the filter.
Product.objects.filter(name__contains=query)
Things missing in html code:
form action attribute
form method attribute
input field name attribute
<!-- add form attributes method and action -->
<form method="POST" action="{% url '<url_name>' %}">
<!-- add input attribute name to identify the field and pass the value in request body -->
<input type='text' placeholder='search houses' name='search_text'>
<button type='submit'>Search</button>
</form>
update views for search
def search(request):
if request.method == 'POST':
# use input field name to get the search text
query = request.POST.get('search_text')
houses = Product.objects.filter(name__contains=query)
context = {
'houses':houses,
}
return render (request, 'searchresult.html', context)

Value of Select Option in Django's Views.py

I am using select tag in template along with a link having 'submit' type inside a form tag. When I select an option from the dropdown and click on the button, it goes to the next page but I am unable to get the value of the options selected. Its showing AttributeError 'Manager' object has no attribute 'month'. Here is my code:
<form method="POST" action="{% url 'results' %}">
{% csrf_token %}
<select name="mahina" id="month">
<option value="all">All</option>
<option value="jan">January</option>
<option value="feb">February</option>
</select>
Search
</form>
Here is my views.py
from django.shortcuts import render
from .models import Results
def allresults(request):
results = Results.objects
if request.method == "GET":
month = results.month
year = results.year
return render(request, 'results/allresults.html', {'results': results}
So to get the form values in the views, you must do like form_val = request.GET.get('field_name', <default_value>) , so to add a few lines in the code
def allresults(request):
# this will get the value of the selected item, print this to know more
mahina = request.GET.get('mahina', None)
#Just writing the below query field month randomly, since the models isn't posted
results = Results.objects.filter(month=mahina)
# We don't need to give GET since by default it is a get request
# Since there are multiple objects returned, you must iterate over them to access the fields
for r in results:
month = r.month
year = r.year
return render(request, 'results/allresults.html', {'results': results}

view that outputs user input on a different url

i created a view + form that creates two widgets + a button for a user. One to select a choice and another to type something in. Now i want to redirect the user after the clicking the button to another webpage displaying his input. (Generally i want to know how to access the userinput and further use it).
This is my form:
class Eingabefeld(forms.Form):
eingabefeld = forms.CharField(label="Flight Number",max_length=20)
a = Auswahlmoeglichkeiten.objects.all()
flughafenname = forms.ModelChoiceField(label="Target Airport",queryset=a,empty_label="-------")
source = forms.CharField(
max_length=50,
widget=forms.HiddenInput(),
required=False
)
This is my views.py:
def get_eingabe(request):
log = logging.getLogger(__name__)
if request.method =="POST":
eingabe = Eingabefeld(request.POST)
log.warn(eingabe)
if eingabe.is_valid():
return HttpResponseRedirect("answerrequest")
else:
eingabe = Eingabefeld()
return render(request, "app_one/labels.html", {"eingabe": eingabe})
def answerrequestseite(request):
return render(request, "app_one/answerrequest.html")
and this is my html ( the included html in this one is just for layout):
<head>
<title>Home</title>
</head>
<form method="post" novalidate>
{% csrf_token %}
{% include "app_one/bootstrap_layout2.html" with form=eingabe %}
<div class="row">
<div class="col-sm-5"></div>
<div class="col-sm-2">
<button type="submit" class="btn btn-primary btn-block">Let's Go!</button>
</div>
<div class="col-sm-5"></div>
</div>
</form>
So basically when opening my webpage "get_eingabe" gets called, and the template gets rendered, now when clicking the button the input is validated and after successfull validation a different URL is opened which will trigger the method "answerrequestseite". Now how do i pass the userinput (eingabefeld and flughafenname) into the other method which will render the template for the second URL?
I read alot about using "request.GET" but i am not quite sure where exactly to place it and how.
After if eingabe.is_valid(): create some variable containing the values you want.
then in you redirect you need to pass those values as get argument like:
your_url/?id=123
Then you can retrieve your variable in your views.py via
request.GET.get('id')
But in your case, you don't want to pass simple id, you want to pass user_input.
One way will be to sanitize this input to make it url compatible.
Otherwise the more flexible solution is to store the values in the session.
Session (via cookie)
# views.py
# Set the session variable
request.session['you_variable_name_here'] = 'the value'
# Retrieve the session variable
var = request.session.get['you_variable_name_here']
https://docs.djangoproject.com/en/2.2/topics/http/sessions/
For your exemple in the first view:
if eingabe.is_valid():
eingabefeld = eingabe.cleaned_data.get('eingabefeld')
flughafenname = eingabe.cleaned_data.get('flughafenname')
request.session['eingabefeld'] = eingabefeld
request.session['flughafenname'] = flughafenname.pk
return HttpResponseRedirect("answerrequest")
In the second view:
def answerrequestseite(request):
eingabefeld = request.session.get('eingabefeld')
flughafenname_pk = request.session.get('flughafenname')
flughafenname = YourFlughafennameModel.objects.get(pk=flughafenname_pk)
return render(request, "app_one/answerrequest.html",{'eingabefeld':eingabefeld,'flughafenname':flughafenname})

Django - get Month and Year from (Datepicker filter data)

This is forms.py
class dateFilter(forms.Form):
date = forms.DateField(input_formats=['%Y-%M-%D'],label='',required=False,
widget=forms.DateInput(attrs={
"placeholder": " Select a date",
"class": "dateClass",
"id": "datepicker",
"name": "dateFilter"}))
This is my views.py
def bsoCharts(request):
#-----------Filter Section------------------------------------------
dateFilter = forms.dateFilter()
FilteredDate = request.POST.get('date')
return render(request, 'BSO/BSO_dashboard2.html', 'dateFilter':dateFilter )
This is my template where I render the form:
<div class="container">
<div class="row">
<div class="col-12 col-sm-12 col-md-6 col-lg-4">
<form action="{% url 'BSO:BSO_Dashboard' %}" method="post" autocomplete="off">
{% csrf_token %}
{{dateFilter}}
</form>
</div>
</div>
</div>
This is my JQuery for the datepicker:
<script>
$("#datepicker").datepicker( {
changeMonth: true,
changeYear: true,
showButtonPanel: true,
dateFormat: 'yy-m-d',
onSelect: function(dateText, inst) {
$(this).parents("form").submit();
}
});
This is the photo image of the datepicker, and the value after selecting a date:
enter image description here
After getting the results back in my views.py using this get method:
FilteredDate = request.POST.get('date')
i'd like to grab only the month and the year using the below method so I can use it as a filter(contains) to another queryset:
FilteredDate.month
However, it's giving me this error:
Django Version: 2.1.5
Exception Type: AttributeError
Exception Value: 'str' object has no attribute 'month'
Please Help!
request.POST is the raw values dictionary that gets submitted. So the fields are almost always strings (or floats/integers). Never the python values they represent.
When working with Django forms, which you're doing, you should always call form.is_valid() to clean the form and then grab the values from form.cleaned_data:
form = forms.dateFilter(request.POST) # create the form with the data submitted
if form.is_valid(): # check the form is valid (which populates cleaned_data at the same time)
filtered_date = form.cleaned_data.get('date') # this is a python date
if filtered_date: # since date is optional, check it was passed
month = filtered_date.month

Should I use request.GET['...'] or form.cleaned_data.get('...')

I have created a function for a search form form my database, method works fine, but I, don't know whether I should use queryBooks = request.GET['queryBooks'] or form.cleaned_data.get('queryBooks')
Here is my code.
# views.py
def SearchBook(request):
error = False
message = ''
books = Books.objects.all()
if 'queryBooks' in request.GET:
queryBooks = request.GET['queryBooks']
if not queryBooks:
error = True
message = u'enter book or author title'
else:
books = Books.objects.filter\
(
Q(book__icontains=queryBooks) | Q(Author__name__icontains=queryBooks)
)
contexto = {'Books': books, 'Error': error, 'Message': message}
return render(request, 'list_of_book.html', contexto)
# list_of_book.html
<form action="" method="get">
<input type="text" name="queryBooks">
<input type="submit" value="search">
</form>
# urls.py
url(r'^books/search/$', SearchBook, name='searchBook'),
There is no form in your view, so
form.cleaned_data.get('queryBooks')
Would give you an error.
In general, I recommend that you learn about Django forms, as they take care of rendering the html, and validating the input from the user. For your specific example, fetching the query string from request.GET is probably ok.