Django print all permissions of a users in template - python-3.x

I am editing the user permissions in templates. And I want to display checked checkbox if user has permissions or unchecked if user has not specific permissions.
My View.py codes are as below.
def EditUserView(request,id=0):
user = User.objects.get(pk=id)
permission = Permission.objects.all()
return render(request,'edituser.html',{"userdata":user,"permissions":permission})
And My templates code are as given below.
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<th>Permissions</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for perm in permissions%}
<tr>
<td id="perm">{{perm}}</td>
<td><input type="checkbox" name="status" id="status" onclick="ChangeUserPermissions(this,userid='{{userdata.id}}',permission='{{perm}}')"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
My objectives of the code is only display checked checkbox if have permissions or unchecked if not have permissions

So you need to register custome tag for this it can be filter:
#register.filter
def has_perm(user, perm):
return user.has_perm(perm)
then in template:
{% for perm in permissions%}
<tr>
<td>{{perm}}</td>
<td><input type="checkbox" name="status" onclick="ChangeUserPermissions(this,userid='{{userdata.id}}',permission='{{perm}}')"
{% if user|has_perm:perm %} selected {% endif %}>
</td>
</tr>
{% endfor %}
those ids on td tags wont be uniqe

Related

Form does not validate. csrf_token included

I have following issue with validate_on_submit() method in my Flask application.
Quick overview what I have:
My form class is created dynamically based on input:
class EditUsers(FlaskForm):
submit = SubmitField('Submit')
def form_builder(roles_list):
class EditUsersForm(EditUsers):
pass
for role in roles_list:
if isinstance(role, tuple) and len(role) == 5:
if not role[2] and role[3]:
setattr(EditUsersForm, f'{role[0]}_{role[4]}_bool', BooleanField(label=role[0]))
setattr(EditUsersForm, f'{role[0]}_{role[4]}_date', SelectField('Expiration Period', choices=choices))
else:
raise IncorrectType
IncorrectType is custom Exception i prepared and choices are created using datetime in same file (This is irrelevant so I am not including it in code).
My route in flask app (simplified):
#### EDIT: I pasted the wrong route, POST and GET Methods are included###
#edit_users.route('/users', methods=['GET', 'POST'])
def users():
... # Some code there
form = form_builder(roles_to_form)
print(form.is_submitted())
print(form.validate())
print(form.validate_on_submit())
return render_template('edit_user.html',
data_dict=data_dict, # in data_dict i pass form fields names and some other data
form=form,
)
My template:
<!-- Some usual stuff goes there css js etc -->
<div >
<form class="form form-horizontal" method="post" role="form" style="margin: auto; text-align: center; width: 40%;">
{{ form.csrf_token() }}
<table class="table" align="center">
<thead>
<th>Role</th>
<th>Expiration Date</th>
<th>Give Role?</th>
</thead>
{% for field in data_dict['id_list'] %}
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]] }}
</td>
<td align="left">{{ form[field[0]] }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="3" align="center">{{ form.submit() }}</td>
</tr>
</table>
</form>
</div>
What is my issue?
When I am hitting my Submit button, is_submitted() returns True but validate() does not, thus I cannot use typical if form.validated_on_submit() as it returns False even when I submit my form.
I dig a little and spot something unusual. I used protected members of form attributes, to check whatever validate() function sees as input:
for name in form._fields:
print(name)
inline = getattr(form.__class__, 'validate_%s' % name, None)
print(inline)
The output (don't mind names of fields):
submit
None
Engineer_2_bool
None
Engineer_2_date
None
Operator_3_bool
None
Operator_3_date
None
Supervisor_4_bool
None
Supervisor_4_date
None
Guest_5_bool
None
Guest_5_date
None
csrf_token
None
I don't know why my form does not have validate_{name} attributes.
I made a working example from your code, and I ended up with the problem you described.
If I reversed well your code, it seems that form[field[1]] is your BooleanField or SelectField. So to render it in a template your have to use form[field[1]]() (can use render_field as well).
So :
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]] }}
</td>
<td align="left">{{ form[field[0]] }}</td>
</tr>
corrected into :
<tr>
<td align="left">{{ field[2] }}</td>
<td align="left">
{{ form[field[1]]() }}
</td>
<td align="left">{{ form[field[0]]() }}</td>
</tr>
https://flask.palletsprojects.com/en/1.1.x/patterns/wtforms/#forms-in-templates
As you are using a FlaskForm, in your template you have to replace {{ form.csrf_token() }} by {{ form.csrf_token }}
https://flask-wtf.readthedocs.io/en/stable/csrf.html#html-forms
[EDIT Does not make any difference]
[Edited after w8eight's comment]
The route is not authorized for POST (and the form makes a POST request as seen in <form class="form form-horizontal" method="post" [...].
So you have to change : #edit_users.route('/users', methods=['GET']) to #edit_users.route('/users', methods=['GET','POST'])
The problem was with type of data passed to choices of SelectField. I passed list of tuples with datetime.datetime to it. When changed type to str everything works smoothly.

Django ListView loop through info created by a class property (not from the database)

On my ListView page, I need to be able to loop through a list of statuses that come from my views.py.
I can do it on the DetailView, but I am struggling with the same process on the ListView.
I have searched and searched and can not seem to find help with my specific problem.
Working code for DetailView:
managers.py
class ICCRequestManager:
...
#property
def statuses(self):
""" Current status of ICC request """
if not self.is_submitted:
yield "Created, not yet submitted"
if self.is_submitted and not self.legal_signoff_status:
yield "Waiting for security review"
if self.is_submitted and not self.security_signoff_status:
yield "Waiting for legal review"
if self.legal_signoff_status and self.security_signoff_status:
yield "Fully reviewed, ICC team is working"
views.py
from . import managers
...
class ICCRequestMixin:
""" Mixin for the request model """
model = models.ICCRequest
context_object_name = 'icc_request'
class ICCRequestDetailView(LoginRequiredMixin, ICCRequestMixin, DetailView):
""" View to see the current status of an ICC request """
template_name = "icc/request_status.html"
def get_context_data(self, **kwargs):
""" Add required context """
context = super().get_context_data(**kwargs)
context["icc_request_manager"] = managers.ICCRequestManager(self.object)
return context
request_status.html
<ul>
{% for value in icc_request_manager.statuses %}
<li>{{ value }}</li>
{% endfor %}
</ul>
The above displays a simple bulleted list as expected.
Problem code:
views.py
class ICCRequestListView(LoginRequiredMixin, ICCRequestMixin, ListView):
""" View to list requests """
template_name = "icc/request_list.html"
paginate_by = 10
def get_context_data(self, **kwargs):
""" Add required context """
context = super().get_context_data(**kwargs)
context["icc_request_manager"] = managers.ICCRequestManager(self.object_list)
return context
Working portion:
request_list.html
<table class="table table-striped table-bordered">
<tr>
<th scope="col">ICC #</th>
<th scope="col">Company</th>
<th scope="col">Brief Description</th>
<th scope="col">LOB</th>
<th scope="col">Requester</th>
<th scope="col">Status</th>
</tr>
{% for request in icc_request %}
<tr>
<th scope="row">{{ request.id }}</th>
<td>{{ request.company_name}}</td>
<td>{{ request.summary }}</td>
<td>{{ request.owner_area }}</td>
<td>{{ request.requested_on_behalf_of }}</td>
<!--- I want the statuses list here --->
</tr>
</table>
Attempt to loop through like on the detail page:
...
<!--- I want the statuses list here --->
<td>
<ul>
{% for status in request.icc_request_manager.statuses %}
<li>
{{ status }}
</li>
{% endfor %}
</ul>
</td>
{% endfor %}
</tr>
</table>
This does not give an error, but it does not display anything (while the request_status.html page does).
Only error is the following linting error on the get_context_data:
"Parameters differ from overridden 'get_context_data' method."
So I figured it out.
1) get_context_data on the ListView has nothing to do with it. Not needed.
2) I needed to change from yields to returning a list:
def statuses(self):
""" Current status of icc request """
statuses = list()
if not self.is_submitted:
statuses.append("Created, not yet submitted")
if self.is_submitted and not self.legal_signoff_status:
statuses.append("Waiting for security sign off")
if self.is_submitted and not self.security_signoff_status:
statuses.append("Waiting for security review")
if self.legal_signoff_status and self.security_signoff_status:
statuses.append("Fully reviewed, ICC team is working")
return statuses
3) Added a method to the model:
#property
def get_icc_request_manager(self):
""" Get the manager for this one request """
# Needed to import managers inside the method to prevent Circular import problem
import icc.managers
mgr = icc.managers.ICCRequestManager(icc_request=self)
return mgr
4) Used with:
<table class="table table-striped table-bordered">
<tr>
<th scope="col">ICC #</th>
<th scope="col">Company</th>
<th scope="col">Brief Description</th>
<th scope="col">LOB</th>
<th scope="col">Requester</th>
<th scope="col">Status</th>
</tr>
{% for request in icc_request %}
{% with request_manager=request.get_icc_request_manager %}
<tr>
<th scope="row">{{ request.id }}</th>
<td>{{ request.company_name}}</td>
<td>{{ request.summary }}</td>
<td>{{ request.owner_area }}</td>
<td>
{% if request.requested_on_behalf_of %}
{{ request.requested_on_behalf_of }}
{% elif request.requested_by %}
{{ request.requested_by }}
{% else %}
{% endif %}
</td>
<td>
<ul>
{% for status in request_manager.statuses %}
<li>
{{ status }} test
</li>
{% endfor %}
</ul>
</td>
{% endwith %}
{% endfor %}
</tr>
</table>

database base values in WTForms without submitting

I am trying to develop a WTForm where users can select one or many part numbers in a table. After the user enters a part number I want to show the master data associated to it (right next to the part number). Such as weight, price etc., rendered in the same template. An SQLIte Table is holding the master data for all part numbers.
At the end, the intention is to sum up the values (price, weight) in a seperate line for the part numbers entered in the WTForm list.
All I find in documentation for WTForm processing is related to "on_submit". But users will never submit the form.
I believe I do not have the right implementation approach right now. First, my current coding is not updating the values in the form, second I dont want to have a submit button in order to see the content_values.
class kundenanalyse_items(FlaskForm):
ka_fm = SelectField('Futtermittel', choices=[('a', 'a Wert'), ('b', 'b
Wert'), ('17', 'irgendwas')])
ka_fm_menge = IntegerField('g/Tag (Tagesplan) bzw. g/Woche (Wochenplan)')
ka_fm_content01 = IntegerField('ka_fm_content01')
ka_fm_content02 = DecimalField('ka_fm_content02')
#app.route('/kundenanalyse', methods=['GET', 'POST'])
def kundenanalyse():
ka_line01 = kundenanalyse_items()
if request.method == 'POST':
flash('Daten an DB gesendet {} : {} + {} :
{}'.format(ka_line01.ka_fm.data, ka_line01.ka_fm_menge.data,
ka_line02.ka_fm.data))
ka_line01.ka_fm_content01.data = '100' * ka_line01.ka_fm_menge.data
ka_line01.ka_fm_content02.data = '200' * ka_line01.ka_fm_menge.data
return redirect(url_for('kundenanalyse'))
return render_template('kundenanalyse.html', ka_line01=ka_line01)
kundenanlyse.html:
{% extends 'layout.html' %}
{% block body %}
{% for message in get_flashed_messages() %}
<div class=flash style="color: orangered;">
{{ message }}
</div>
{% endfor %}
<form method="POST", action="/kundenanalyse")>
<div class="tg-wrap"><table class="tg" style="undefined;">
<tr>
<th class="tg-wh92">{{ ka_line01.ka_fm.label }}</th>
<th class="tg-wh92">{{ ka_line01.ka_fm_menge.label }}</th>
<th class="tg-wh92">{{ ka_line01.ka_fm_content01.label }}</th>
<th class="tg-wh92">{{ ka_line01.ka_fm_content02.label }}</th>
</tr>
<tr>
<td class="tg-e3ma">{{ ka_line01.ka_fm }}</td>
<td class="tg-sh4c">{{ ka_line01.ka_fm_menge }}</td>
<td class="tg-hkz2">{{ ka_line01.ka_fm_content01 }}</td>
<td class="tg-hkz2">{{ ka_line01.ka_fm_content02 }}</td>
</tr>
</table>
</div>
<input type="submit" value="Submit">
</form>
{% endblock %}
thank you in advance.
Michael

How do I iterate zip list in jinja2 using for loop and display values in HTML table?

I was trying to iterate zip list in jinja2 and display values in HTML table but failed at every single try with a blank page, however, I can display values in the Unordered list like as follows.
<ul>
{% for bus, info in jnjbus_info %}
<li>{{bus}}</li>
<li>{{info}}</li>
{% endfor %}
</ul>
This is my flask/function where I passing values to template:
#app.route('/busses')
def busses():
bus_type = ['AC', 'NON-AC', 'Sleeper', 'NON-Sleeper']
bus_info = ['1010', '2020', '3030', '4040']
return render_template('busses.html', jnjbus_info=zip(bus_type, bus_info))
I'm rendering template called busses.html
Here's the script:
<table style="width:100%">
<tr>
<th>Bus Type</th>
<th>Bus Information</th>
</tr>
{% for bus, info in jnjbus_info %}
<tr>
<td>{{bus}}</td>
<td>{{info}}</td>
</tr>
{% endfor %}
</table>
you don't have the
<tbody> </tbody>
tag in your page i added it and it works:
<table style="width:100%">
<tr>
<th>Bus Type</th>
<th>Bus Information</th>
</tr>
<tbody>
{% for bus, info in jnjbus_info %}
<tr>
<td>{{bus}}</td>
<td>{{info}}</td>
</tr>
{% endfor %}
</tbody>
</table>
here is how it looks like :
The code provided in this question is bug-free, however, the problem caused by port=5000 and may be browser cache as well. While tackling with the bug I have written a similar script py and html and screen shot .and ran on port=8888 which works like charm. Note : consider running the same application on different ports and clearing browser cache.

Trying to use laravel pagination breaks my controller/view

I'm trying to get Pagination working in Laravel. I've not used pagination before so am trying to use some examples from the docs and google results. I'm wondering if I need to turn 'pagination' on somewhere in config.
Here's my simple working controller:
public function get_index() {
$locations = Location::all();
return View::make('location.index')->with('locations', $locations)->render();
}
When I try and add pagination like this it breaks:
public function get_index() {
$locations = Location::paginate(5);
return View::make('location.index')->with('locations', $locations)->render();
}
..and I get the error:
Unhandled Exception
Message:
Error rendering view: [location.index]
Trying to get property of non-object
Here's my location.index view:
#layout('layouts.blank')
#section('content')
<div class="row">
<div class="twelve columns">
<div role="main" id="content">
<h3>Locations - All</h3>
#if($locations)
<table class="twelve">
<thead>
<tr>
<th style="text-align: left;">Address</th>
<th>Area</th>
<th>Region</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
#foreach($locations as $location)
<tbody>
<tr>
<td style="text-align: left;">{{ $location->company,', ',$location->add_name,', ',$location->add_city }}</td>
<td> – </td>
<td> – </td>
<td>{{ HTML::link('location/update/'.$location->id, '',array('class'=>"foundicon-edit updateicon")) }}</td>
<td>{{ HTML::link('location/delete/'.$location->id, '',array('class'=>"foundicon-remove warnicon")) }}</td>
</tr>
</tbody>
#endforeach
</table>
#else
Looks like we haven't added any locations, yet!
#endif
<p>{{ HTML::link('location/create', 'Create a location', array('class'=>"small radius button")) }}</p>
</div>
</div>
</div>
#endsection
I hadn't read deeply enough into the subject. It's now working and here's what I had to change in the view:
//from:
#foreach($locations as $location)
//to:
#foreach($locations->results as $location)
That returned just 5 results. Then to add links to the footer of my table I added this HTML/Blade:
<tfoot>
<tr>
<td colspan="5"> {{ $locations->links() }} </td>
</tr>
</tfoot>
Hope someone else benefits as I didn't find this terribly clear in the docs.

Resources