Opening a user uploaded PDF in django - python

I have a webapp where a user can upload a pdf file. I want the user to be able to click a button to be able to see the file in the browser.
I'm not sure how to link the pdfs as when they are uploaded they get given a random name by django in my static root. eg: hello_0akcjs.pdf
My View
def pdf_view(request, pk):
Menufile = Menu.objects.get(pk=pk).menuFile
with open('Menufile', 'r') as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = 'inline;filename=some_file.pdf'
return response
URL
path('<int:pk>/', pdf_view, name='pdf_view'),
Model
class Menu(models.Model):
name = models.CharField(max_length=50)
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
menuFile = models.FileField(upload_to='menus')
Template
{% for menu in menus %}
View Menu {{ menu.name }}
{% endfor %}
As it stands, everything works, except i just dont know how to get the pdf to be rendered at the URL for that model instances PK.

I was making it far too complicated. All i needed to do was reference the menuFile URL in the template.
Example:
View Menu

To display a pdf you have to use an embed tag,
<embed src={% url 'pdf_view' menu.pk %} width="500" height="375" type="application/pdf">

Related

Download file stored in a model with FileField using Django

I'm planning on creating a simple file upload application in Django (incorporated in some bigger project). For this one, I'm using two links: /files/ - to list all the uploaded files from a specific user, and /files/upload/ - to display the upload form for the user to add a new file on the server.
I'm using a PostgreSQL database, and I'm planning to store all my files in a File model, that looks like this:
class File(models.Model):
content = models.FileField()
uploader = models.ForeignKey(User, on_delete=models.CASCADE)
My file upload view looks like this:
#login_required
def file_upload_view(request):
if request.method == "POST" and request.FILES['file']:
file = request.FILES['file']
File.objects.create(content=file, uploader=request.user)
return render(request, "file_upload_view.html")
else:
return render(request, "file_upload_view.html")
while my file list view looks like this:
#login_required
def file_view(request):
files = File.objects.filter(uploader = request.user)
return render(request, "file_view.html", {'files': files})
The problem is, I want my file_view() to display all files uploaded by a certain user in a template (which I already did), each file having a hyperlink to its download location. I've been trying to do this in my file list template:
{% extends 'base.html' %}
{% block content %}
<h2>Files of {{ request.user }}</h2>
<br>
{% for file in files %}
<a href="{{ file.content }}" download>{{ file.content }}</a>
{% endfor %}
{% endblock %}
but my browser is trying to download some .htm page, even if the file I've uploaded is of type .txt.
My question is: do I also need to upload the file in a certain directory, before adding it to the model? Do I need to actually add the file's URL as a new field in my model? Aren't the files automatically uploaded to my PostgreSQL database?
Any help would be greatly appreciated.
Thank you.
I guess you should show a folder to where you want to save your files like this:
content = models.FileField(upload_to='/myfiles/')
And then you can show the url ("{% url 'file.url' %}") in your html because the database actually saves the url of your file and stores the file itself in the folder you've showed in your model.

How do I html format my blog post in django?

So I want to make a blog post with HTML formatting from the admin page directly. For example from the models.py, you see the description is a TextField. When I go to the admin page to make a blog post, I want to be able to add HTML tags to my blog. So the text field will have HTML content. While I call the blog post onto the HTML template I want it to read the description as a HTML file and not just a text field.
models.py
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
date = models.DateField()
Blog.description at admin page
<HTML>
<body>
<p>Welcome to my first blog post!!</p>
</body>
</html>
blog.html
<h1>{{ blog.title }}</h1>
<hr>
<p>{{ blog.description }}</p>
Any help is appreciated. Thanks!
You can render it with the |safe template filter [Django-doc]. This will disable escaping HTML fragments, and it will thus no longer convert < to < for example:
<h1>{{ blog.title|safe }}</h1>
<hr>
<p>{{ blog.description|safe }}</p>
You however might want to take a look at the django-ckeditor package [GitHub] which offers a dedicated field, widget, etc. to enable editing the text with respect to rendering.

Save .docx file django for specific user

I'm creating a docx file with user input in django. For now when the submit button is clicked the download link generates and users can download the file. However I want to save the file in file store and create a template where the user can see all the docx files (or a hyperlink) that he has created in the past. "Somewhat like a database"
models.py
class Timetables(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
default=1, related_name='timetables_files', null=True)
timetable_files = models.FileField(
null=True, blank=True, upload_to='word_documents')
views.py
def school_view(request):
if request.method == 'POST':
worddocument = docx.Document()
documenttitle = worddocument.add_heading(
school_name_view.title(), 0)
file = io.BytesIO()
worddocument.save(file)
response = HttpResponse(
content_type='application/vnd.openxmlformats-
officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename =quicktimetable.docx'
worddocument.save(response)
path = join(settings.MEDIA_ROOT, 'word_documents',
'quicktimetable.
file = open(path, 'w+b')
return response
class TimetablesView(ListView):
model = Timetables
template_name = 'quickmain/timetables_list.html'
timetables_list.html
{% if user.is_authenticated %}
{% for f in files %}
{{ f.files.url }}
{% endfor %}
{% for timetable_files in user.timetables_files.all %}
<embed src = "{{timetable_files.timetable_files.url}}" target="__blank">
{% endfor %}
{% else %}
How can I save the files which are generated and show all the files related to that user on a different a template.
I have a FileField in my models.py but no idea how to make use of it. I got a suggestion to regenerate file whenever users ask for it but I have no idea about that as well.
You have to create the relation between the file and user model.
Example
in your model
class DocxFile(models.Model):
user = models.ForiegnKey(User) #your user model name
file = models.FileField('upload_to='/')
then in your views
from yourappname.models import DocxFile
def docs_file(request):
files = DocxFile.object.filter(user=request.user)
return render('your template path', {'files':files})
in your template
{% for f in files%}
{{f.file.url}}
{% endfor %}

Django how to open and display saved docx or pdf documents

I'm currently working on a question bank website using Django 1.87 that allow users o login and view saved past questions. so far i have been able to display links to the past questions in the database base on user selection. the past questions are uploaded as docs or PDF format and stored in the media directory.
I want logged in users to be able to open and read the content of the past question before deciding whether to print or download it. so far i have been able to display a list of links to the documents and when i click on a link it downloads the document to my computer. what i really want to achieve is for users to be able to click on a link and open the document from within the browser before clicking a download buttenter code hereon or print.
here are my codes:
models.py
class QuestionBank(models.Model):
date = models.DateField(_("Date"),default=date.today)
class_level = models.ForeignKey(ClassLevel)
course_name = models.CharField(max_length=350)
course_code = models.CharField(max_length=20)
question_papers = models.FileField(upload_to = 'Question_Papers/ %y/%m/%d')
views.py
def Questions(request, sel_course):
context = RequestContext(request)
SelCourse = sel_course.replace('_',' ')
context_dict = {'SelCourse':SelCourse}
try:
Quest_For_course = QuestionBank.objects.filter(course_code = SelCourse)
context_dict['Quest_For_course'] = Quest_For_course
except course_code.DoesNotExist:
pass
return render_to_response('Qbank/QuestionsPage.html', context_dict, context)
in my Template i have this
QuestionsPage.html
<title> Question Papers </title>
<body>
<h2> LIST OF QUESTION PAPERS FOR {{selCourse}} </h2>
<h3> Select question to view, download or print it</h3>
{% if Quest_For_course %}
<ul>{% for ques in Quest_For_course %}
<li><a href="{{ques.question_papers.url}}">
{{ques.question_papers}} </a></li>
{%endfor%}
</ul>
{%else%}
<strong> THERE ARE NO AVAILABLE QUESTION FOR THIS CLASS AT THE MOMENT </strong>
{%endif%}
</body>
how do i make past question documents view-able? on a form that has download and print button. thanks

get_full_path in django model method

I'm just starting with django (and python too, to be honest)
I am trying to get a model method that would cut the self.slug from current URL and return it to template.
This is the method I tried:
class Category(models.Model):
...
def remove_filter(self):
url = HttpRequest.get_full_path()
slug = '/' + self.slug
return url.replace(slug, '')
But as you can imagine, it doesn't work.
Template's snippet:
{% for object in active_filters %}
<li><i class="icon-remove"></i>{{ object }}</li>
{% endfor %}
My core goal here is to have a front-end icon with a url altered by removing current object's slug.
I have no idea how to do it through views, but I'm open to any suggestions.
def category_page(request, url):
slugs = url.split('/')
active = Category.objects.filter(slug__in=slugs)
sorted_slugs = []
for i in active:
sorted_slugs.append(i.slug)
if slugs != sorted_slugs:
url = '/'.join(sorted_slugs)
return redirect('http://127.0.0.1:8000/catalog/' + url)
inactive = Category.objects.exclude(slug__in=slugs)
return render(request, 'category.html', {'active_filters': active,
'inactive_filters': inactive})
Thanks.
You can send a list of all active slugs to the template and then build a custom template filter to construct the modified url.
views.py
# Send your list of active slugs to the template
return render(request, 'category.html', {
'active_filters': active,
'inactive_filters': inactive,
'slugs': slugs,
})
tags_and_filters.py
import copy
from django import template
register = template.Library()
#register.filter(name='remove_filter')
def remove_filter(category, slugs):
copied_slugs = copy.copy(slugs)
slug = category.slug
if slug in copied_slugs:
copied_slugs.remove(slug)
return '/'.join(copied_slugs)
your template
{% for object in active_filters %}
<li>
<i class="icon-remove"></i>{{ object }}
</li>
{% endfor %}
Your remove_filter method has no access to the current request. HttpRequest is the class, not the current request instance.
I suggest that you rewrite remove_filter as a custom tag or filter. That way your function can access the category and request instance. You will have to activate the request template context processor in your settings as well.

Categories

Resources