Value of Select Option in Django's Views.py - django

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}

Related

date-format not working on html page with datepicker

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")

django, views direct to a another html page

I am using Django for develop a website. The website is intended to use to search information stored in a MySQL database.
This is the current basic flow of the web site.
1) index.html - this has a form to select an option
2) according the option, users will redirect to search.html (include a form)
3) once the user provides the criteria, the result will be displayed in reply.html
In my views.py , I have two functions.
from django.shortcuts import render
from website.models import WebsiteRepository
from .forms import SearchForm
from .forms import SelectTypeForm
def Search(request):
if request.method == 'POST':
#do something
return render(request, 'reply.html', {'env_dict':env_dict})
else:
#do something
return render(request, 'search.html', context = context)
def index(request):
if request.method =='POST':
#do something
return render(request, 'search.html', context = context)
else:
#do something
return render(request, 'index.html', context= context)
When I go to index.html page, I can select a option and it will direct me to search.html. After, I fill the form there and submit, it wont give me the reply.html page.
I have a feeling that, I could make this work by changing urls.py.
from django.urls import path
from website import views
urlpatterns = [
path('', views.index, name='index'),
#path('search/', view.Search, name ='Search')
]
I tried to google it. But its too much details and Iam kind of lost.
Do any of you guys know how to achieve this?
Thanks
search.html
{% extends "base_generic.html" %}
{% block content %}
<h3>Welcome to search information Repository</h3>
<form method="post">
{% csrf_token %}
{{form.as_p}}
<button type = 'submit'>submit</button>
</form>
{% endblock %}
index.html
{% block content %}
<h3>Welcome to information Repository</h3>
<form method="post">
{% csrf_token %}
{{form.as_p}}
<button type = 'submit'>submit</button>
</form>
just for clarify things more, ill add the forms.py too
from django import forms
from .models import WebsiteRepository
class SearchForm(forms.Form):
websiterepository = WebsiteRepository
env_indicators = websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator' )
OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
year = forms.ChoiceField(choices=OPTIONS)
class SelectTypeForm(forms.Form):
OPTIONS = (('1', 'Envirnmental Indicators'),('2','Economic Indicators'),('3','Social Indicators'),)
types = forms.ChoiceField(choices=OPTIONS)
Your code is wrong on many points.
First thing first: for a search, you want a GET request, not a POST (POST is for updating the server's state - adding or updating your database mostly). This is the semantically correct method (since you want to GET data), and it will allow a user to bookmark the url.
Second point: you don't want to submit the search form to the index view but to the search view. No need for redirects etc, just use the {% url %} templatetag to fill the action attribute of your form (you of course need to have a 'Search' url in your urls.py):
<form method="get" action="{% url 'Search' %}">
{% csrf_token %}
{{form.as_p}}
<button type = 'submit'>submit</button>
</form>
if you want to have this form on more than one page (which is often the case for search forms), use an inclusion tag tha will take care of creating an unbound SearchForm and render the template fragment.
Then in your search view, you only want GET requests, and do not use two different templates, this will only lead to useless duplication.
def Search(request):
form = SearchForm(request.GET)
# use the form's data - if any - to get search results
# and put those results (even if empty) in you context
return render(request, 'reply.html', {'env_dict':env_dict})
And finally, your search form is totally broken:
class SearchForm(forms.Form):
# this is totally useless
websiterepository = WebsiteRepository
# this will only be evaluated once at process startup, so you will
# get stale data in production - and probably different data
# per process, in a totally unpredictable way.
# You need to either put this in the form's __init__ or wrap it
# in a callable and pass this callable
env_indicators = websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator' )
# are you going to manually add a new year choice every year ???
OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
year = forms.ChoiceField(choices=OPTIONS)
For the "indicators" ChoiceField you want something like:
def get_indicators_choices():
return Websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
class SearchForm(forms.Form):
# IMPORTANT : we are NOT calling the function here, just
# passing it (python functions are objects) to the field, which
# will call it everytime the form is instanciated, so you don't
# have stale data
indicator = forms.ChoiceField(
choices=get_indicator_choices,
label='Indicator')
As a last note: be consistent with your namings (ie why name one view in all lower (index) and capitalize the other (Search) ? Whichever convention you choose (I strongly suggest respecting pep8 here), at least stick to it for the whole project.
The problem is that code is not redirecting to /search, instead rendering search.html after post from index.html.
Try doing like-
views.py-
#your code
def index(request):
#do something
if request.method == 'POST':
return redirect('Search')
else:
#render index.html
def search(request):
#do something
if request.method == 'POST':
#render reply.html
else:
#render search.html
Another way to achieve this is if you specify action in your form so that form posts on /search.
search.html
<form method="post" action="/search">
{% csrf_token %}
{{form.as_p}}
<button type = 'submit'>submit</button>
</form>

Django dropdown choice selection

I would like to create 'dropdown' menu in template1 with a choice selection. dropdown should list unique dates from the range of Room instances 'created_date' attribute.
Once choice is selected and submitted it should be passed to template2. It needs to be passed to template2 so the view that renders template2 can filter Room instances by selected choice and display filtered instances in template2.
Can somebody list for me the required steps I need to complete to do what's written above ? I would read about these required steps so can achieve this task.
Below is my class.
class Room(models.Model):
flat = models.ForeignKey(Flat)
room_name = models.CharField(max_length= 10)
room_value = models.PositiveSmallIntegerField(default=0)
created_date = models.DateField(auto_now_add= True)
I have tried so far to create such dropdown menu and can do it but I do not know how to pass selected choice to template2 so selected choice can be used be the view that renders template2 to filter instances of Room class.
EDIT
I have created view, form and template but I have not managed to pass update_date yet.
views.py
def room_choice(request):
form = RoomChoiceForm()
if request.method == 'POST':
form = RoomChoiceForm(request.POST)
if form.is_valid():
room_choice = form.save(commit=False)
print room_choice
return redirect('/blocks/all_rooms',request)
return render(request, 'prostats/choicesform.html',{'form':form})
forms.py
class RoomChoiceForm(forms.ModelForm):
class Meta:
model = RoomLog
fields = ('room',)
choicesforms.html
<form method="post" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Submit</button>
</form>
url
url(r'^choices/$', views.room_choice, name='choices'),
url(r'^all_rooms/$', views.AllRoomsView.as_view(), name='roomsdetails'),
If I understand correctly:
First step is a form where the user selects some options from a list. The result is something like: choices=A,B,C
Taking the choices from step 1 (A,B,C) you want to display something based on that selection.
Simply use a regular HTML form with method GET for step 1:
<form method="GET" action="{% url 'name-of-url-of-step2' %}">
<select multiple>
<option name="choices" value="A"...>
<option name="choices" value="B"...>
<option name="choices" value="C"...>
<option name="choices" value="D"...>
</select>
</form>
Submitting this form will call the url specified in the form action with the query string generated from the form fields: http://.../<url-to-step2>/?choices=A&choices=B (depending on the selection)
Note that it is normal that the query string will be discarded should there be one in the action url, and it will be replaced with the form data.
The Django view that implements step 2 can now read the query parameters: self.request.GET.getlist('choices') will return ['A','B'].

redirect from django admin action intermediate page to change form page

I am trying to build an admin action 'download_selected' which will download selected models. When the action is selected, I redirect to an intermediate page so that users can select a download format. When a user selects a download format and clicks on 'download', it downloads the file. But stays on the same intermediate page. How do I redirect it back to change form admin page? This redirection that I want is similar to django 'download selected file' default admin action. Thanks.
Here is my code.
admin.py
class SelectDownloadFormatForm(forms.Form):
DOWNLOAD_TYPE_CHOICES=[('csv','csv'),
('json', 'json'),
('xml','xml')]
_selected_action = forms.CharField(widget=forms.MultipleHiddenInput)
download_type = forms.ChoiceField(label=_('Select a Download type'), choices=DOWNLOAD_TYPE_CHOICES, widget=forms.RadioSelect())
def download_selected(self, request, queryset):
import csv
from django.http import HttpResponse, HttpResponseRedirect
import StringIO
form = None
if 'download' in request.POST:
form = self.SelectDownloadFormatForm(request.POST)
if form.is_valid():
dtype = form.cleaned_data['download_type']
print dtype
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="export.csv"'
writer = csv.writer(response)
writer.writerow(['id', 'name', 'qid' ,'label', 'name', 'field'])
count = 0
for s in queryset:
questions_query = ParentModel.objects.filter(parent_form_id = s.id)
for q in questions_query:
writer.writerow([s.id, s.name, q.id, q.label, q.name, q.field])
count += 1
plural = ''
if count != 1:
plural = 's'
self.message_user(request, "Successfully downloaded %d survey response%s in %s format" % (count, plural, dtype))
return response
if not form:
form = self.SelectDownloadFormatForm(initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)})
return render(request,'admin/download_type.html', {'items': queryset,
'download_type_form': form,
})
download_selected.short_description = "Download selected forms"
download_type.html
{% extends "admin/base_site.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ download_type_form }}
<p>Following survey will be downloaded with corresponding responses:</p>
<ul>{{ items|unordered_list }}</ul>
<input type="hidden" name="action" value="download_selected" />
<input type="submit" name="download" value="Download" />
</form>
{% endblock %}
I added an extra button to go back
Go Back
You'll need javascript for the redirect.
You can use jQuery File Download so you can do:
$.fileDownload('/url/to/download').done(function {
// redirect
})
Not sure if you can combine it with a form post.

How to get information from Django_tables2 row?

I have declared a table and want to fetch the row's value which is checked using checkboxfield. Any help, how can i write this event in my views so that everytime I select a row and hit submit button, it returns the row's values.Code goes like this:
class mytables(tables.Table):
new_database = tables.CheckBoxColumn()
student =tables.Column(accessor='Student')
Class = tables.Column(accessor='class')
And in my templates a submit button.
You need to choose a suitable value for the CheckBoxColumn. Generally if you're displaying a queryset, you'll use the pk of each object for the CheckBoxColumn. In your case this would look like:
class EnrollmentTable(tables.Table):
selection = tables.CheckBoxColumn(accessor='pk')
student = tables.Column()
class = tables.Column()
Then you'll need to render the table within a form, so that the user can submit the form, e.g.:
<form action="/someurl/" method="post">
{% load render_tables from django_tables2 %}
{% render_table table %}
<input type="submit"/>
</form>
Then you'll need a view hooked up to /someurl/. In your case the view will need to look at the POST variable selection:
def someview(request):
if request.method == "POST":
pks = request.POST.getlist("selection")
selected_objects = SomeModel.objects.filter(pk__in=pks)
# do something with selected_objects
else:
# ...