Django : Zipping selected object's pdf - python

I have an Index view that displays Trainer name, location, etc as well s a button to download their Profile(already in database as a pdf). I search and filter these based on some parameters. Now i want to be able to select a few of these and download the selected Trainer Profiles.Im new to Django and can't figure out how to do that. Here's my code. It says 'FieldFile object is not callable'
views.py
def download(request):
import zipfile
import os
file = zipfile.ZipFile("C:\\Downloads\\test.zip", "w")
filelist = []
filelist+= 'Trainer.checkboxoption' in request.REQUEST
for i in filelist:
file.write(i)
file.close()
return render(request,'trainer/index.html')
index.html
<form action="download/" method="post">
<div class="caption">
<div >
<table style="width:100%" class="table">
<tr>
<th>#</th>
<th>Name</th>
<th>Technology</th>
<th>Location</th>
<th> View</th>
<th>Download</th>
<th>Delete</th>
</tr>
{% for trainer in all_trainers %}
<tr>
<td><input type="checkbox" id="trainer{{ forloop.counter }}" name="trainer" value="{{ trainer.id }}"></td>
<td> <a href="/trainer/{{ trainer.id }}">{{ trainer.name }}</td>
<td>{{ trainer.technology }}</td></a>
<td>{{ trainer.location }}</td>
<!-- View Details -->
<td>View Details</td>
<td>Download PDF</td>
<!-- Delete Album -->
<td><form action="trainer/{{trainer.id }}/delete/" method="post">
{% csrf_token %}
<input type="hidden" name="trainer_id" value="{{ trainer.id }}" />
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form></td>
</tr>
{% endfor %}
</table>
</div>
</div>
<input type="submit" value="Download ZIP">
</form>

views.py:
def download(request):
import zipfile
filef = zipfile.ZipFile("test.zip", "w")
var = request.POST.getlist('checks')
pdfprofile = []
for i in var:
trainer= Trainer.objects.get(pk=i)
pdfprofile.append(trainer.trainer_profile)
for i in pdfprofile:
filef.write("D:\\Django\\myproduct\\media\\"+str(i))
filef.close()
response = HttpResponse(open("test.zip", "rb").read(), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=test.zip'
return response

Related

How to load content dynamically from database into Bootstrap modal using Django

I am working on a testing app that lists out users from the database in a HTML table, what I want to achieve is this, when you click on any icon for a particular record or row the full detail of that record is displayed in a Bootstrap Modal. My problem is how do I implement my views, urls, and also my Templates? Do I need Javascript help here? Cause in PHP this is done easily without JavaScript. Plesae I will prefer code samples as a correction to my issue thanks.
Here is my view
def users(request):
get_users = User.objects.all()
return render(request, 'classwork_app/users.html', {'users':get_users})
My urls
from classwork_app import views
app_name = 'classwork_app'
urlpatterns = [
path('', views.users, name='users'),
]
Templates
<table class="table table-bordered">
<tr>
<th>S/N</th>
<th>Username</th>
<th>Firstname</th>
<th>Lastname</th>
<th colspan="2">Action</th>
</tr>
{% if users %}
{% for u in users %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ u.username }}</td>
<td>{{ u.first_name }}</td>
<td>{{ u.last_name }}</td>
<td style="font-size: 12px"><a data-toggle="modal" href="#MyModal{{ u.id }}"><i class="fa fa-eye"></i></a></td>
</tr>
{% endfor %}
{% endif %}
</table>
<div id="#MyModal{{ u.id }}" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{{ u.first_name }} {{ u.last_name }}</h4>
</div>
<div class="modal-body">
<p>
Username: {{ u.username }}
Firstname: {{ u.first_name }}
Lastname: {{ u.last_name }}
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
you can try putting your modal html code inside the for user iterator. This way it will load a modal with user content for every user in your list (not very recommended if you have a lot of data, can cause performance issues)

How to hard delete a user from SQLite database using loops from Flask's View

I've been working on a really simple,maybe trivial, flask application that manages users' credentials, like a sysadmin page (change username, password, privileges, email).
Right now I've written the following code in HTML:
<div id="signup-box" class="signup-box" style=" background-color:rgb(149, 202, 202); width: 60%;">
<table class="table" style="background-color:#ffffff00;">
<thead >
<tr>
<th style="text-align:center; vertical-align:inherit;">Username</th>
<th style="text-align:center; vertical-align:inherit;">Role</th>
<th style="text-align:center; background-color:rgba(104, 159, 223, 0.384);">Control</th>
<tr>
</thead>
<tbody>
{% for i in range(0,lenUser) %}
<tr class="tr">
<td style="text-align:center; vertical-align:inherit;">{{ users[i] }}</td>
<td style="text-align:center; vertical-align:inherit;">{{ roles[i] }}</td>
<td style="text-align:center;">
<button form="edit_form" type="submit" value="Edit" class="button is-warning is-focused" style="margin-right: 45px;">Edit User</button>
<button form="delete_form" type="submit" value="Delete" class="button is-danger is-focused" style="margin-right: 45px;">Delete User</button>
<form id="edit_form" action="{{ url_for('edit_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="EDIT">
</form>
<form id="delete_form"action="{{ url_for('delete_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
in Python:
#app.route("/delete_user/")
def delete_user():
if not session.get('logged_in'):
return redirect(url_for('login'))
con = sqlite3.connect('sqlite:///accounts.db')
cur = con.cursor()
cur.execute('DELETE FROM User WHERE id = "' + request.args.get('id')+ '"')
cur.commit()
con.close()
return flask.jsonify({'success':"True"})
And as a Python helper to fetch my users:
def fetch_users():
with session_scope() as s:
usrs = s.query(tabledef.User.username).order_by(tabledef.User.username).all()
tblUsrs = df.from_records(usrs)
return(tblUsrs)
Now, what it does is that it fetches my users as a dataframe and it outputs them row by row in my html table, which is what it was intended to do. But I also want to delete the specific user when I press the button "Delete" in the HTML page, right? Problem is that I can't seem to find a way to select the specific id of the user from the following lines:
<form id="delete_form"action="{{ url_for('delete_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
</form>
How can I fix that? Because it is in a loop and every time the string I get is that of the first line

Django: Url can't be resolved

I've made an Application containing List of trainers. My Index View Displays these trainer profiles from the database. I intend to implement a sear bar to filter these results. I am not getting what i'm doing wrong. As soon as i mention the url in action of the search for, it displays reverse match error
url's.py :
#/trainer/
url(r'^$', views.IndexView.as_view(),name='index'),
#/trainer/<trainer_id>/
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(),name='details'),
#/trainer/trainer/add
url(r'trainer/add/$', views.TrainerCreate.as_view(), name='Trainer-add'),
#/trainer/trainer/<album_id>
url(r'trainer/(?P<pk>[0-9]+)/$', views.TrainerUpdate.as_view(), name='Trainer-update'),
#/trainer/trainer/add
url(r'trainer/(?P<pk>[0-9]+)/delete/$', views.TrainerDelete.as_view(), name='Trainer-delete'),
url(r'^search/$', views.search, name='Search'),
views.py
def search(request):
query = request.GET['q']
trainer= Trainer.objects.filter(name__icontains=query)
return render(request,'trainer/index.html', {'trainer': trainer})
search form in my base template
<form class="navbar-form navbar-left" method="get" action="{% url 'trainer:Search' %}">
<div class="form-group">
<input type="text" id="searchBox" class="input-medium search-query" name="q" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
index.py
<table style="width:100%" class="table table-hover">
<tr>
<th>#</th>
<th>Name</th>
<th>Technology</th>
<th>Location</th>
</tr>
{% for trainer in all_trainers %}
<tr>
<td><input type="checkbox" id="trainer{{ forloop.counter }}" name="trainer" value="{{ trainer.id }}"></td>
<td> <a href="{% url 'trainer:details' trainer.id %}"> {{ trainer.name }}</td>
<td>{{ trainer.technology }}</td></a>
<!-- View Details -->
<td>View Details</td>
<td>Download PDF</td>
<!-- Delete Album -->
<td>
<form action="{% url 'trainer:Trainer-delete' trainer.id %}" method="post">
{% csrf_token %}
<input type="hidden" name="trainer_id" value="{{ trainer.id }}" />
<button type="submit" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
</td>
</tr>
{% endfor %}
</table>
You need {% url 'Search' %} and not {% url 'trainer:Search' %}; the : is for when you have namespaced your urls.
change this line
<form class="navbar-form navbar-left" method="get" action="{% url 'trainer:Search' %}">
to
<form class="navbar-form navbar-left" method="get" action="{% url 'Search' %}">
Are you including the urls.py somewhere?
Otherwise you need to add caret ^ at the start of your regex.
url(r'^trainer/search/$', views.search, name='Search'),

Url not changing , just render the template after login

The URL is not changing and data is not fetching after user login.
After Login the url not changed(i expected to change to 127.0.0.1:8000/employer/home)
#login_required
def home(request):
emp=Employer.objects.get(user=request.user)
jb=Job.objects.filter(employer=emp).order_by("-postdate")
return render(request,'employer/home.html',{'jobs':jb})#,{'employer':emp})
employer/home.html
<table class="table table-hover table-bordered">
<tr><th>Job ID</th><th>Title</th><th>Posted on</th></tr>
{% for job in jobs %}
<tr>
<td>{{ job.pk }}</td>
<td>{{ job.title }}</td>
<td>{{ job.postdate }}</td>
</tr>
{% endfor %}
</table>
login.html
<form class="form-signin" action="" method="post">{% csrf_token %}
<h4 class="form-signin-heading">Sign in to my account...</h4>
{% if errors %}
<p class="text-error">Sorry, that's not a valid username or password</p>
{% endif %}
<input type="text" id="username" class="input-block-level" name="username" placeholder="UserID">
<input type="password" id="password" class="input-block-level" name="password" placeholder="Password">
<p style="text-align:right;">Forgot your password?</p>
<button class="btn btn-large btn-success" type="submit" value="login">Sign in</button>
</form>
You need to tell it where to go after login using the next url parameter:
<form class="form-signin" action="{% url django.contrib.auth.views.login %}?next=employer/home/" method="post">
or set the LOGIN_REDIRECT_URL in settings:
The URL where requests are redirected after login when the contrib.auth.login view gets no next parameter.

Wring file retrieved using Blobstore

I have form upload and handler which allows download uploaded files from blobstore.
The problem is when I click Download button of any related-field it downloads the same file every time. I.e. I've uploaded 3 files (1.txt, 2.txt, 3.txt) and it always downloads only 1.txt whenever I clicked another Download buttons. You can see it at http://my77notes.appspot.com/show (or http://my77notes.appspot.com/upload first for uploading your own files).
When I've researched source code it shows me different keys for every hidden fields..
What did I wrong?
Here is my files:
template file:
<h2>Files uploaded to Blobstore</h2>
<table border="3">
<tr>
<td>#</td>
<td>Filename</td>
<td>Content-Type</td>
<td>Creation</td>
<td>Size</td>
<td>Download</td>
</tr>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
</form>
</table>
handler.py
class BlobstoreServeHandler(RequestHandler, BlobstoreDownloadMixin):
def post(self):
blob_info = blobstore.BlobInfo.get(self.request.form.get('blobkey'))
return self.send_blob(blob_info, save_as=True)
urls.py
rules = [
Rule('/', endpoint='index', handler='apps.77notes.handlers.IndexPageHandler'),
Rule('/upload', endpoint='upload/html', handler = 'apps.77notes.handlers.BlobstoreUploadFormHandler'),
Rule('/upload/handler', endpoint='upload/handler', handler='apps.77notes.handlers.UploadHandler'),
Rule('/download', endpoint='download/html', handler = 'apps.77notes.handlers.BlobstoreDownloadFormHandler'),
Rule('/download/file', endpoint='download/file', handler='apps.77notes.handlers.BlobstoreServeHandler'),
Rule('/show', endpoint='show/html', handler='apps.77notes.handlers.ShowUploadedFilesHandler'),
]
variables
blob_files = uploaded_files_to_blobstore = blobstore.BlobInfo.all()
download_blob = self.url_for('download/file')
Thanks!
Of course it's always the first. You're declaring three hidden fields with the same name but various values. How could the server understand you want “the hidden field nearest to the download button I clicked”?
You could do this with Javascript but it's overkill. Maybe you should rather create forms for each item, but I'm not sure it is HTML-valid.
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td><form class="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form></td>
</tr>
{% endfor %}
If you don't like this, you could also provide the index of the desired blobkey within the download submit button. Something like this:
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td>
<input type="submit" name="dl{{ loop.counter0 }}" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
Then, server-side, you get the right blobkey using:
# don't forget to handle errors here, NTUI
ind = int([_[2:] for _ in self.request.form if _.startswith('dl')][0])
blobkeys = self.request.form.getlist('blobkey')
blobkey = blobkeys[ind]
# stuff
if you what to download through form you need to do as many form as blob you have
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form>
</td>
</tr>
{% endfor %}
or you can do it by ordinary A tag like this <a href = '/get/{{ file.key() }}'>

Categories