I submit a form with two inputs to search a table. My code doesn't get the value of 'namequery' instead of displaying all data in table. What did I do wrong here? Thanks for any help!
The url is
http://..../chinook/search/?namequery=rand&affquery=
search.html
<h3 class="labs-background-title">Search results for <em id="search-name">{{ namequery }}</em>:</h3>
{% if object_list %}
{% for obj in object_list %}
{{ obj.lname }} <br />
{{ obj.clustering }} <br />
{% endfor %}
{% else %}
<h3>No matches found.</h3>
{% endif %}
views.py
class SearchView(generic.ListView):
model = Pitable
template_name = 'chinook/search.html'
def get_queryset(self):
try:
namequery = self.kwargs['namequery']
except:
namequery = ''
if (namequery != ''):
object_list = self.model.objects.filter(lname = namequery)
else:
object_list = self.model.objects.all()
return object_list
The return page display all data, shows the {{namequery}} is empty. Thanks!
There are quite a few things wrong here.
Firstly, 'namequery' is not a URL kwarg, it is a GET query parameter. You need to get it from self.request['namequery'].
Secondly, never ever use a blank except. The only exception that could possibly happen there is KeyError, so catch that. But a better way of writing all four lines would be:
namequery = self.request.GET.get('namequery')
Thirdly, to display the value of namequery in the template you need to add it to the context data.
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
context['namequery'] = self.request.GET.get('namequery')
return context
Related
My flask form is not getting validated.
#admin_blueprints.route('/ManageMovies',methods=['GET', 'POST'])
def ManageMovie():
form = SetShowForm(request.form)
if request.method == 'POST' and form.validate():
print(form.movie.data)
return redirect(url_for('admin.AdminHome'))
engine = create_engine('mssql+pyodbc://DESKTOP-6UNRAN0/movie_f?driver=SQL Server?
Trusted_Connection=yes')
form.movie.choices = [(movie.m_id, movie.m_name)for movie in (engine.execute('select * from
MovieMaster'))]
form.show_time.choices = [(time.s_id, time.s_time) for time in (engine.execute('select * from
ShowTime'))]
return render_template('manage_movies.html',form=form)
my template code is
{% extends "master.html" %}
{% block content %}
<form method="POST">
{{ form.hidden_tag() }}
{{form.movie.label}}{{form.movie(class="form-control")}}
<br>
{{ form.show_time.label }} {{form.show_time(class="form-control")}}
<br>
{{form.price.label}} {{ form.price(class="form-control") }}
<br>
{{form.submit(class="btn btn-success")}}
</form>
{% endblock %}
my flask form
class SetShowForm(FlaskForm):
movie = SelectField('Movie Name', choices=[])
show_time = SelectField('Set Show Time',choices=[])
price = IntegerField('Price')
submit = SubmitField("Set")
Once I click on my submit button, the same page gets rendered again instead of entering my (if request.method == 'POST' and form.validate():) statement and printing the data. I have no idea what is going wrong. I am filling all the fields. Are there any rule for form validation.
I believe you need to use:
if form.validate_on_submit():
And you don't need to check for "POST" because validate_on_submit does that too.
Try it
#admin_blueprints.route('/ManageMovies',methods=['GET', 'POST'])
def ManageMovie():
form = SetShowForm()
if form.validate_on_submit():
print(form.movie.data)
return redirect(url_for('admin.AdminHome'))
return render_template('manage_movies.html',form=form)
And set choices values in setShowForm() directly
I'm trying to get the form to create the fields based on what exam page the user is on. In the error page, all local variables have the correct value for form and view, but I keep getting ExamQuestion object not iterable and an error at line 0 of the template. It also highlights the render() at line 44 in the view as the source of the problem. If I change line 28 from exam__name=exam_name to exam__name="exam_name", basically turning the variable into a str, the page runs but no data is passed.
In the error console choice_list shows querysets as individual list items as it should for forms.py
How do I make the object ExamQuestion iterable? I've been stumped for a week now. I've written a hundred ways at this point.
I know it's listing questions instead of answers for the questions, I'm just trying to get it to load ANY queryset and freaking run at this point.
view
def exampage(request, exam_name):
exams = Exam.objects.all()
questionlist = ExamQuestion.objects.filter(exam__name=exam_name)
choicelist = ExamChoice.objects.filter(question__exam__name=exam_name)
form = ExamTest(request.POST, exam_name=exam_name)
if request.method == "POST":
if form.is_valid():
#form.save()
#choice = form.cleaned_data.get('choice')
return redirect('exampage.html')
return render(request, 'exams/exampage.html', {'exams': exams,'questionlist': questionlist, 'exam_name': exam_name, 'choicelist': choicelist, 'form': form, 'choice': choice})
else:
form = ExamTest(exam_name=exam_name)
return render(request, 'exams/exampage.html', {'exams': exams,'questionlist': questionlist, 'exam_name': exam_name, 'choicelist': choicelist, 'form': form})
form
class ExamTest(forms.Form):
def __init__(self, *args, **kwargs):
exam_name = kwargs.pop('exam_name')
super(ExamTest, self).__init__(*args, **kwargs)
#choice_list = [x for x in ExamQuestion.objects.filter(exam__name="dcjs01")]
#choice_list = []
x = ExamQuestion.objects.filter(exam__name=exam_name)
#for q in x:
# choice_list.append(q)
self.fields["choices"] = forms.ChoiceField(choices=x, label="testlabel")
template
{% extends 'portal/base.html' %}
{% block content %}
<h1>{{ exam_name }} Page</h1>
{{ exam_id }}
<hr>
{% for exam in exams %}
<li>{{ exam }}</li>
{% endfor %}
<h1>! {{ questionlist }} !</h1>
<form method="post" action="#">
{% csrf_token %}
formtest{{ form }}
<button type="submit"> finish test </button>
</form>
{% endblock %}
The first part of the question is - you getting the ExamQuestion not iterable error:
here I think is the problem, that you, in the Form init function pass the Queryset (objects.filter(xxx)), but not the .all() which will select it.
the second thought is - would'n it be better to pass the questions as a parameter to the Form, as you previously selected all the question for this particular exam?
figured it out. choices=x needs to be a tuple
self.fields['name'] = forms.ChoiceField(choices=tuple([(name, name) for name in x]))
My models looks this way
class Test(models.Model):
name = models.CharField(max_length=255)
test_plan = models.FK(TestPlan)
class TestPlan(models.Model):
name = models.CharField(max_length=255)
class Result(models.Model):
user = models.FK(User)
test_plan = models.FK(TestPlan)
test = models.FK(Test)
result = models.Boolean()
In the case I have a plan object in my view, I can access all tests by doing plan.test_set.all(). But is there a way to append all existing results to that query (so a result object is attached to a given test case, if it exists).
=====
I am trying to run the following
def get(self, request, *args, **kwargs):
task = get_object_or_404(Plan, id=kwargs.get('id'))
return render(request, self.template_name,
{"task": task})
def post(self, request, *args, **kwargs):
data = request.POST
task = get_object_or_404(Task, id=kwargs.get('id'))
tc = get_object_or_404(Test, id=data.get('tc_id'))
tc_result, _ = Result.objects\
.get_or_create(task=task, test=tc,
result=data.get('tc_result_status'))
return HttpResponse("OK")
And in template:
{% for test in task.tests_set.all %}
{{ test }}(here I want to render test result, if it I have one for given test in given plan, for current user)
{% endfor %}
You're looking to access a reverse one to many relationship? Just iterate in the same way you accessed tests_set.
{% for test in task.tests_set.all %}
{{ test }}
{% for result in test.result_set.all %}
{{ result }}
{% endfor %}
{% endfor %}
To filter the results in task.tests_set.all() or test.result_set.all() you need to use prefetch_related with custom Prefetch object.
Something like:
task = get_object_or_404(
TestPlan.objects.prefetch_related(
Prefetch('test_set', queryset=Test.objects.prefetch_related(
Prefetch('result_set', queryset=Result.objects.filter(user=request.user))
))
),
id=kwargs.get('id')
)
And in template:
{% for test in task.test_set.all %}
{% for result in test.result_set.all %}
{{ result }}
{% endfor %}
{% endfor %}
I'm going through the book Django 1.0 Website Development where you build a small social bookmarking application. I'm at chapter 5 where you create a form to add bookmarks and although I've followed the instructions and have been struggling on this error for days. I get the error:
AttributeError at /save/
'set' object has no attribute 'get'
The error is being thrown on line 6 of the template {{ form.as_p }}
The views.py code is:
def bookmark_save_page(request):
if request.method == 'POST':
form = BookmarkSaveForm(request)
if form.is_valid():
# create or get link.
link, dummy = Link.objects.get_or_create(
url=form.cleaned_data['url']
)
# create or get bookmark.
bookmark, created = Bookmark.objects.get_or_create(
user=request.user,
link=link
)
# if bookmark is being updated, clear the old tag list
if not created:
bookmark.tag_set.clear()
# create new tag list
tag_names = form.cleaned_data['tags'].split()
for tag_name in tag_names:
tag, dummy = Tag.objects.get_or_create(name=tag_name)
bookmark.tag_set.add()
# save bookmark to database
bookmark.save()
return HttpResponseRedirect(
'/user/%s/' % request.user.username
)
else:
form = BookmarkSaveForm()
variables = RequestContext(request, {
'form' : form
})
return render_to_response('bookmark_save.html', variables)
And the template code is:
{% extends "base.html" %}
{% block title %}Save Bookmark{% endblock %}
{% block head %}Save Bookmark{% endblock %}
{% block content %}
<form method="post" action=".">{% csrf_token %}
**{{ form.as_p }}**
<input type="submit" value="save" />
</form>
{% endblock %}
Any help would be much appreciated as I'm stuck at this point in the book and can't seem to find an answer. Thanks!
Is this an error for you?
for tag_name in tag_names:
tag, dummy = Tag.objects.get_or_create(name=tag_name)
bookmark.tag_set.add() # not adding the tag?
Shouldn't it be: bookmark.tag_set.add(tag) ? The .add() doesn't actually cause an error, but I know you aren't adding your tag.
Without seeing the traceback, I'm guessing.
My other guess is that you might be using the RequestContext wrong?
return render_to_response('bookmark_save.html',
{'form': form},
context_instance=RequestContext(request))
I believe the way you are using it now is meant for the non-shortcut approach of using an HttpResponse()
I want to display my non_field_erors in my template. So far, I can display all kind of errors of my forms with:
-> base.html
{% if form.errors %}
{% for field in form %}
{% if field.errors %}
<div class="ui-state-error ui-corner-all notification" >
<p>
<span class="ui-icon ui-icon-alert"></span>
{{ field.label_tag }}:{{ field.errors|striptags }}
<a class="hide" onClick="hideBar(this)">hide</a>
</p>
</div>
{% endif %}
{% endfor%}
{% endif %}
AND
{{ form.non_field_errors }}
I've added a new form which has only an IntegerField:
class MerchantForm(forms.ModelForm):
price = forms.IntegerField(widget=forms.TextInput(attrs={'class':'small'}))
def clean_price(self):
price = self.cleaned_data.get('price')
if price == 120:
raise forms.ValidationError('error blah.')
return price
When I post price as 120, I don't get any validation errors in my page.
And my view is:
def bid(request,product_slug):
.
.
form = MerchantForm()
context = RequestContext(request,{
'form':form,
....
})
if request.method == 'POST':
form = MerchantForm(request.POST)
if form.is_valid():
return HttpResponse('ok')
# else:
# return HttpResponse(form.errors.get('__all__'))
return render_to_response('bid.html',context_instance=context)
I can retrieve the error with commented lines but I don't want to do that in views.py. Any ideas ?
Oh dear.
First of all, why are you asking about non_field_errors when the code snippet you post clearly has the error as being raised in clean_price, and therefore is associated with ths price field?
Secondly, your view code is upside down. You create an empty form instance, and add it to the context. Then you create another form instance, bound to the POST data, but don't put it into the context. So the template never sees the bound form, so naturally you never see any validation errors in the template.