I am trying to set the initial choices in a dropdown, on profile edit for selecting Business type. But I want the dropdown to already have the current instance' selections already chosen. But I just cant figure out how to render this on the frontend. I heard of a select option that jinja template offers, to do this?
I will take a code snippet from my app,
def edit_profile(request):
request_user = request.user
# FOR SENDING USER TO SERVER
if request.method == 'POST':
template_name = 'business/profile_view.html'
first_name = request.POST['first_name']
business = request.POST.getlist('business_type', '')
if business == '':
pass
try:
user_obj = Account.objects.get(email=request.user)
""" Loop over business types and assign to user """
user_obj.business.clear()
for _business in business:
user_obj.business.add(_business)
return redirect('/auth/edit_profile/')
except Exception as e:
message = {"message": "Profile edit ERROR"}
return render(request, template_name, message)
# FOR SERVER TO USER
if request.method == 'GET':
template_name = 'business/profile_view.html'
context = dict()
user_obj = Account.objects.get(email=request.user)
context['business_type'] = user_obj.business
if request.path == '/auth/edit_profile/':
return render(request, template_name, context)
elif request.path == '/auth/edit_profile_edit/':
return render(request, 'business/profile_edit.html', context)
And my Template
<select class="selectpicker" name="business_type" multiple="multiple"title="Select a category">
{% for business in business_types %}
<option value="{{ business.id }}">{{ business.name }}</option>
{% endfor %}
</select>
You can add "selected" to your views context:
context['selected'] = business # or however you are identifying the selected
then in the html you can add the selected tag with an ifequal statement:
{% for business in business_types %}
<option {% if ifequal business.name selected.name %}selected{% endif %}
value="{{ business.id }}">{{ business.name }} </option>
{% endfor %}
or if the context is a list, then you can use {% if business in selected_businesses %}
{% for business in business_types %}
<option {% if business in selected_businesses %}selected{% endif %}
value="{{ business.id }}">{{ business.name }} </option>
{% endfor %}
I'd recommend looking into Django's forms system. It does a lot of the work of setting up forms, rendering widgets, and even validating your data for you. You can also send forms with the current instance already filled in
Related
In templates folder I have index.html and template.html
I'm trying to GET data from a form in index.html, process the data and POST the results in template.html as .
index.html:
<form method="POST">
<select class="browser-default custom-select" name="regions_brato">
<option selected>Open this select menu</option>
{% for each,key in new_dict.items() %}
<option value="{{each}}">{{each}}</option>
{% endfor %}
</select>
<select name="list_status">
{% for key in listStatus %}
<option value="{{key}}">{{key}}</option>
{% endfor %}
</select>
<input type="submit">
</form>
template.html:
..
<body>
{% for each,key in res.items() %}
<p>{{each}}</p>
{% endfor %}
</body>
..
Flask:
#application.route('/', methods=['GET', 'POST'])
def form():
listStatus = ['en', 'fr', 'bg']
new_dict = {}
with open('fr.json') as json_file:
data = json.load(json_file)
for each in data:
new_dict.setdefault(each['admin'], []).append(each['city'])
if request.method == 'GET':
return render_template('index.html', listStatus=listStatus, default="en", new_dict=new_dict)
else:
return redirect(url_for('template'))
#application.route('/template')
def template():
region = request.form["regions_brato"]
lang = request.form["list_status"]
res = get_feel(region, lang, 30)
return render_template("template.html", res=res)
Can anyone point me to where exactly I have messed up the GET/POST requests and any possible solution ?
I don't know if you messed up something, but I know you can't test posting without some help, it is not viewable. You need an app like Postman or a server. Maybe it is just that.
So I have a form that updates a key_instance object with a borrower. Currently my app needs the user to enter the name of the borrower, but I want it to display a dropdown list of data from another model the user model to select from, is there anyway to do this in a class based view? Here are my views.py and my template. What I was thinking is that I would like to use a get_list_or_404 on the user model and display it as a drop down list in the template and use that selection to populate the form field.
I manged to get the dropdown list to display in my template but I'm not sure as to how to save that value in my views.
Does anyone know if this is the right way or if this is doable? Thank you!!
views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(Users)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = UpdateKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = form.cleaned_data['borrower']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
form = UpdateKeyForm(initial={'borrower': 'N/A'})
return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst':key_inst})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
<table style="display: inline-flex">
{{ form}}
</table>
<select name = 'name'>
{% for name in names %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
Here is how I manged to do it, Not sure if this is the best 'pythonic' or best practice. Please let me know if it's not.
my views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(User)
# If this is a POST request then process the Form data
if request.method == 'POST':
name = request.POST['name']
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = name
key_inst.save()
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
pass
return render(request, 'catalog/keyinstance_request_update.html', {'keyinst':key_inst, 'names':names})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
</br>
<select name = 'name' required>
{% for key in names %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
I have a custom filter in django admin interface
class ClipExcludeRightsFilter(ListFilter):
title = 'rights'
parameter_name = 'exclude_rights'
template = 'admin_mod/filters/exclude_rights.html'
def lookups(self, request, model_admin):
result = (
('avod', 'avod'),
('svod', 'svod'),
('est', 'est'),
('tvod', 'tvod')
)
return result
def queryset(self, request, queryset):
if self.value():
urls_owner = ClipRestriction.objects.exclude(vod_system=self.value()).values_list('clip_id', flat=True)
return queryset.filter(
pk__in=urls_owner
)
And in interface it returns list (select) and I can select just one attribute. But I need to implement multiple select. I found, that default template for this is template/admin/filter.html
{% load i18n %}
<h3>{% blocktrans with filter_title=title|capfirst %} By {{ filter_title }} {% endblocktrans %}</h3>
<select class="combobox">
{% for choice in choices %}
<option{% if choice.selected %} selected{% endif %} value="{{ choice.query_string|iriencode }}" >{{ choice.display }}</option>
{% endfor %}
</select>
Maybe I need to write my own template but no idea how to (I need to filter selected options instantly).
I just selected all option:selected using jquery and then pass it as a parameter in my url.
I'm making a post from a webpage that is generated dynamically from Django DB content. The data is put into a combo box and is supposed to send the customer id back to Django so I can parse some more queries with it and then display only the customers data that was selected.
However instead of retruning my post data it returns the csrf token instead of the posted data.
<form method='post' action='' id='customers'>
{% csrf_token %}
<select>
{% for item in customer %}
<option value={{ item.customer_id }} name='customer_id'>{{ item.customer_name }}</option>
{% endfor %}
<input type = 'submit' value='Edit'>
</select>
{{ post }}
{{post.customer_id}} #doesnt work either.
this is what it returns:
<QueryDict: {u'csrfmiddlewaretoken': [u'CpzKrwmZsmfiiNHngNWDFSNxqUoBykYO']}>
def portal(request):
customers = Customer.objects.all()
if request.method == 'POST':
vm_groups = Vm_group.objects.all()
vms = Vm.objects.all()
selected_customer = request.POST.copy()
#selected_customer_id = selected_customer['customer_id']
post = selected_customer
context = Context({'customer': customers, 'vm_groups':vm_groups, 'vms':vms, 'post':post,
})
return render(request, 'portal.html', context)
else:
context = Context({'customer': customers,})
return render(request, 'portal.html', context)
Also how would I get just the customer_id from the returned data once it works correctly?
selected_customer = request.POST.copy()
selected_customer_id = selected_customer['customer_id']
Like so?
You need to put the name attribute on the select element, not the option.
But you should probably be using Django's forms framework, anyway.
As #Daniel told that, You need to add name field to select tag not for option tag,
<select name='customer_id'>
{% for item in customer %}
<option value={{ item.customer_id }} >{{ item.customer_name }}</option>
{% endfor %}
<input type = 'submit' value='Edit'>
</select>
I use Django Endless Paginator plugin.
I try to change the value of ENDLESS_PAGINATION_PER_PAGE from template side.
As default is 10.
I want to realize some dropbox where the user can change between (Example: 10,20,50,100 Objects).
Thanks for answer, but something not work property.
1. I have view.py
def adv_search(request):
objects = None
if request.GET.get('key'):
form = AdvancedSearchForm(request.GET)
if form.is_valid():
repo = Repository()
objects = list(repo.find_objects('*'+form.cleaned_data['key'] +'*', type=FileObject, chunksize=20))
return render(request, 'templates/adv_search.html', {'form': form, 'objects': objects })
return render(request, 'templates/adv_search.html', {'form': AdvancedSearchForm(), 'objects': objects})
2. Then forms.py
class AdvancedSearchForm(forms.Form):
key = forms.CharField(max_length=500, label="", widget= forms.TextInput(attrs={'class': 'label'}))
show_props = forms.MultipleChoiceField(choices = (("pid", "pid"),("title", "title"),("type","type"),("source","source"),("date","date"),("publisher","publisher"),("subject","subject"),("label","label"),("cDate","cDate"),("mDate","mDate")),required=False, widget=forms.CheckboxSelectMultiple(attrs={'class': 'my-class'}))
paginator = forms.ChoiceField(choices =(('10', '10'),('20','20'), ('50','50'), ('100','100')) ,required=False, )
3. adv_search.html
{% paginate paginator objects %}
{% for obj in objects %}
...
<div class="paginator">
{% get_pages %}
{{ pages.first_as_arrow }}
{% show_pages %}
{{ pages.last_as_arrow }}
<form method="get">
{{ form.paginator }}
<input type="submit" Value="Go">
</form>
{{ pages.total_count }} total objects
</div>
Everything works except select
Thanks Andrey
You can have a form which will set pagination per page and then use that submitted value in template. Here is an example:
View
from django.shortcuts import render
from .models import Entry
def endless_view(request):
pagination_per_page = request.GET.get('per_page', 10)
entries = Entry.objects.all()
return render(request, 'some_template.html', {'pagination_per_page':
pagination_per_page, 'entries': entries})
Template
{% extends 'base.html' %}
{% load endless %}
{% block content %}
{# #}
<form action="" method="get">
<select name="per_page">
<option value="10">10 per page</option>
<option value="20">20 per page</option>
<option value="50">50 per page</option>
<option value="100">100 per page</option>
</select>
<input type="submit" Value="Go">
</form>
{% paginate pagination_per_page entries %}
{% for entry in entries %}
{# your code to show the entry #}
{% endfor %}
{% show_pages %}
{% endblock content %}
Reference
http://django-endless-pagination.readthedocs.org/en/latest/templatetags_reference.html