Django Include Not Including Content - django

I want to use {% include %} to include a second form on a page, but the form is empty..
views.py:
def year_form(request):
thing_list = Thing.objects.all()
if request.method == 'POST':
form = YearBrowseForm(request.POST)
if form.is_valid():
year = form.cleaned_data['year']
return HttpResponseRedirect(reverse('browse_years', kwargs={'year':year}))
else:
form = YearBrowseForm()
return render(request, 'browse-year.html', {'form':form, 'thing_list':thing_list})
forms.py:
class YearBrowseForm(forms.Form):
year = forms.ChoiceField(choices=YEARS_EMPTY, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
url:
url(r'^browse/years/(?P<year>\d+)/$', 'my_app.views.browse.year_form', name='browse_years'),
html:
{% extends 'base.html' %}
{% block content %}
{% include 'browse-year.html' %}
{% endblock %}
browse-year.html:
<form action='' method='post' enctype='multipart/form-data'>
{{ form.as_p }}
{% csrf_token %}
</form>
This renders an empty form (i.e. the source shows that a form is being included, but it is empty of content). What am I missing here? This is a continuation of this question that I am trying to solve in a different method by using {% include %}. Thanks for your ideas!

This happens because you are rendering browse-year.html:
return render(request, 'browse-year.html', {'form':form, 'thing_list':thing_list})
You should be rendering the other html, the one you didn't gave a name, but starts with
{% extends 'base.html' %}
only by rendering that one you extend the base, and the other content appears.

Related

How to Create a UpdateForm with TemplateView?

I need to create a UpdateForm with a TemplateView. Why with TemplateView? Because, I has a attribute what is geo_location, and I'm using LeafLet maps, and LeafLet maps doesn't work with generic.UpdateView or others the same type.
Here my views from Update:
class UpdateStore(LoginRequiredMixin, TemplateView):
template_name = 'store_form'
success_url = reverse_lazy('register:store_list')
def post(self, request, *args, **kwargs):
store_id = kwargs['store']
store = get_object_or_404(Store, pk=store_id)
form = StoreForm(request.POST, on_edit=True)
if form.is_valid():
form.save()
return redirect(reverse('register:store_list'))
else:
context = self.get_context_data()
context['data_form'] = form
return render(request, self.template_name, context)
return self.get(request)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
store_id = self.kwargs['store']
store = get_object_or_404(Store, pk=store_id)
data = {
'name': store.name,
'description': store.description,
'address': store.address,
'geo_loc': store.geo_loc,
'opened': store.opened
}
context['editing'] = True
context['data_form'] = StoreForm(initial=data, on_edit=True)
context['store'] = store
return context
Here is my template code:
{% extends 'base.html' %}
{% load bootstrap3 %}
{% load leaflet_tags %}
{% block extra_css %}
{% leaflet_css plugins="forms" %}
{% endblock %}
{% block body %}
<h1> Update Store </h1>
<form method="POST">
{% csrf_token %}
{{ form }}
{% buttons %}
<button type="submit">
{% bootstrap_icon "star" %} Save
</button>
{% endbuttons %}
</form>
{% endblock %}
{% block extra_js %}
{% leaflet_js plugins="forms" %}
{% endblock %}
I trying this, but in my template, the Forms doesn't load, and my template are blanked :(. Someone knows why? I need another method for get anything else?
Thanks.
The problem with your code is that you place the form in the data_form key of the context:
context['data_form'] = StoreForm(initial=data, on_edit=True)
and then on the template you try to use it with {{form}} instead of {{data_form}}. After that the form should be rendered.

Using redirect sends me to /tag/?search=input instead of /tag/input (Django URL argument from form)

I have a page where there is a path /tag/name_of_tag and you can see all posts tagged with that tag.
Inside the page, you can also select another tag in a form and go to that tag.
The problem is that instead of going to /tag/searched_tag, it goes to /tag/?search=searched_tag
How can I change it doesn't leave the ?search= part?
urls.py:
url(r'tag/(?P<input_tag>\w+)$', views.tag_view, name='tag'),
views.py:
def tag_view(request, input_tag):
form = TagSearchForm()
if request.method == 'GET':
form = TagSearchForm(request.GET)
if form.is_valid():
input = form.cleaned_data['search']
print(input)
return redirect('fortykwords:tag_view', input)
else:
form = SearchForm()
latest_post_list = Post.objects.filter(tags=input_tag, status__exact="published")
paginator = Paginator(latest_post_list, 3)
page = request.GET.get('page')
posts = paginator.get_page(page)
context = {'latest_post_list': latest_post_list, 'page_tag': input_tag, 'form': form}
return render(request, 'fortykwords/tag.html', context)
forms.py:
class TagSearchForm(forms.Form):
search = tagulous.forms.SingleTagField(
tag_options=tagulous.models.TagOptions(
autocomplete_view='fortykwords:post_tags_autocomplete'
),
label='Tags',
required=True,
help_text=_('Filter by lead tags. You can organize leads by any tag you want.'),
)
tag.html:
{% extends "base_generic.html" %}
{% block content %}
<form action="." method="get">
{{ form }}
<input type="submit" value="Submit" />
</form>
<h3>Posts with the tag {{ page_tag }}</h3>
{% if latest_post_list %}
<ul>
{% for post in latest_post_list %}
<li> {{ post.author }} {{ post.pub_date }}
<br>
{{ post.title }}</li>
{% for tag in post.tags.all %}
{{ tag.name }}
{% endfor %}
{% endfor %}
</ul>
{% else %}
<p>No posts are available.</p>
{% endif %}
{% endblock %}
You need to provide the argument input to redirect method as input_tag=input.
Example:
return redirect('fortykwords:tag_view', input_tag=input)
It's showing as /tag/?search=searched_tag because your form is submitting by GET but never getting to the redirect. It seems is_valid() is returning False.
I've tested a very similar version of your code and don't think it's a bug in tagulous, but would still be interested to know what had gone wrong (I wrote tagulous). Spotted a couple of places you can streamline your code a bit, so try::
def tag_view(request, input_tag):
# Can't see any POSTs in your example, so you can pass the form GET here
# Might also be nice to pass the original tag in so it shows in the form
form = TagSearchForm(request.GET, initial={'search': input_tag})
# The form already has the GET, so you can go straight into the is_valid
if form.is_valid():
input = form.cleaned_data['search']
print('Valid: ', input)
return redirect('fortykwords:tag_view', input)
else:
print('Invalid: ', form.errors, form.non_field_errors)
# You can remove the else for if not GET, which would never be reached
# on to pagination as before
(although fwiw I'd recommend ipdb instead of print)

How to change template based on user authentication in django

If user successfully login i need to show one template. if user not login i need to show another template.
I created two templates one is base.html another one is base_login.html template.
IF user successfully login i need to call base_login.html other wise base.html. i am using below to achieve this. it's not giving expected result. How do achieve this?
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
{% extends "base_login.html" %}
{% else %}
{% extends "base.html" %}
{% endif %}
If your template goes invalid, I suggest you to it at the views.py, an example:
from django.shortcuts import render, render_to_response
def homepage(request):
template_name = 'homepage.html'
extended_template = 'base_login.html'
if request.user.is_authenticated():
extended_template = 'base.html'
return render(
request, template_name,
{'extended_template': extended_template, ...}
)
# homepage.html
{% extends extended_template %}
{% block content %}
{% if request.user.is_authenticated %}
Hello {{ request.user }}
{% endif %}
{% endif %}
Note: if function of render still doesn't work well, please try with render_to_response such as this answer: https://stackoverflow.com/a/1331183/6396981

Correct <form action=" " URL for a SessionWizardView

I have been having some trouble getting a Django SessionWizardView to submit data to my database and I am trying to isolate the issue.
I note from the Form documentation
As well as its elements, a form must specify two things:
where: the URL to which the data corresponding to the user’s input should be returned
how: the HTTP method the data should be returned by
and
Form data sent back to a Django Web site is processed by a view,
generally the same view which published the form. This allows us to
reuse some of the same logic.
Currently I am using <form action="/surveyone/" method="post"> which I believe is correct.
The issue is that my view is called class SurveyWizardOne(SessionWizardView): but if I try to use this in the form action I get an error as soon as I click Next on the first page of the survey.
Question: Based on the below is action="/surveyone/" correct?
Thanks
urls.py
url(r'^surveyone/$', SurveyWizardOne.as_view([
SurveyFormIT1,
SurveyFormIT2,
Start,
SurveyFormA,
SurveyFormB,
SurveyFormC,
SurveyFormD,
SurveyFormE,
SurveyFormSpike1,
SurveyFormF1,
SurveyFormF2,
SurveyFormF3,
SurveyFormDV1,
SurveyFormF4,
SurveyFormF5,
SurveyFormF6,
SurveyFormSpike2,
SurveyFormDV2,
SurveyFormF7,
SurveyFormF8,
SurveyFormF9,
SurveyFormDV3,
SurveyFormDV4,
SurveyFormDV5,
SurveyFormG,
SurveyFormH,
SurveyFormI
])),
views.py
class SurveyWizardOne(SessionWizardView):
def get_context_data(self, form, **kwargs):
context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)
step = int(self.steps.current)
....
....
return context
def done(self, form_list, **kwargs):
return render(self.request, 'Return_to_AMT.html', {
'form_data': [form.cleaned_data for form in form_list],
})
wizard_form.html
{% extends "base.html" %}
{% load i18n %}
{% block head %}
{{ wizard.form.media }}
{% endblock %}
{% block content %}
<div class="main_content">
<p>Page: {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="/surveyone/" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
Since your form is submitting to the same url, you can simply use action="". If you prefer, you can use action="/surveyone/"
If you don't want to hardcode the url in your template, then you need to name your url patterns:
url(r'^surveyone/$', SurveyWizardOne.as_view([
SurveyFormIT1,
SurveyFormH,
...
]), name="survey_one"),
You can then use the url tag in your template:
action="{% url 'survey_one' %}"

Django 1.5 Creating multiple instances of model in ModelAdmin

I'm kind of puzzled with this task:
I have 2 tables: User, Codes
I want to generate randomly codes in a specific pattern.
I've already written that part as a function, but it's hard to implement the function
in the ModelAdmin.
So I would be very pleased if someone knows a trick to accomplish this.
It would be enough to have a button in the User form to envoke the function, which then creates these codes.
But how do I implement such a button?
Is there a way to to this?
EDIT: typo
SOLUTION:
Since I want to generate vouchers for a particular user I can edit the admin.py like this:
class MyUserAdmin(UserAdmin):
def vouchers(self, obj):
return "<a href='%s'>Generate vouchers</a>" % reverse(gen_voucher_view, kwargs={'user':obj.pk,})
vouchers.allow_tags = True
list_display = (..., 'vouchers')
which represents a clickable link in the admin view of my User model.
Now I connect the link to my view in urls.py by adding
url(r'admin/gen_vouchers/(?P<user>\w+)/$', gen_voucher_view, name='gen_voucher_view')
to urlpatterns.
For creating the vouchers I provide a form in forms.py
class VoucherGeneratorForm(forms.Form):
user = forms.CharField(User, required=True, widget=forms.HiddenInput())
amount = forms.IntegerField(min_value=0, max_value=500, required=True)
readonly = ('user', )
In views.py I'm adding my view function:
#login_required
def gen_voucher_view(request, user):
if request.method == 'POST': # If the form has been submitted...
form = VoucherGeneratorForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# GENERATE vouchers here by using form.cleaned_data['amount']
# and user (generate_vouchers is a self defined function)
vouchers = generate_vouchers(user, form.cleaned_data['amount']
# set error or info message
if len(vouchers) == form.cleaned_data['amount']:
messages.info(request, "Successfully generated %d voucher codes for %s" % (form.cleaned_data['amount'], user))
else:
messages.error(request, "Something went wrong")
u = User.objects.get(pk=user)
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
return render_to_response('admin/codes.html', {'request': request, 'user':user, 'form':form, 'userobj': u}, context_instance=RequestContext(request))
else:
form = VoucherGeneratorForm(initial={'user':user}) # An unbound form
Last but not least create a template admin/codes.html where my form is displayed:
{% extends "admin/base_site.html" %}
{% load i18n admin_static static %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% trans 'Home' %}
›
{% trans 'Users' %}
›
{% trans 'Vouchercodes' %}
›
Voucher Generator
</div>
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
{% block content %}
<div id="content-main">
{% if request.user.is_active and request.user.is_staff or userobj and userobj.is_active and userobj.is_staff %}
<h1 id="generator_title">Generate vouchers for {{user}}</h1>
<form id="formular_generator" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<table>{{ form }}</table>
<button id="generatebutton" type="submit" name="action" value="generate">Generate</input>
</form>
{% else %}
<p>{% trans "You don't have permission to access this site." %}</p>
</div>
{% endif %}
{% endblock %}
{% block sidebar %}
{% endblock %}
Done!
To export them in a pdf I used admin actions, as propsed by Sumeet Dhariwal below.
U mean that you need to run a script from within the admin ?
If so check out django-admin-tools
http://django-admin-tools.readthedocs.org/en/latest/dashboard.html
SOLUTION FOUND:
no that was not what i meant, because I want to generate vouchers for 1 particular user and not for more, but that's a good remark.