I'm trying to show a preview of a pdf loaded via form.
I also share the error when I try to do python3 manage.py makemigrations
A help is greatly appreciated.
Python Version: 3.5
Django Version: 1.11
Now I share the code
models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
from PyPDF2 import PdfFileReader
from wand.image import Image
from .extra import ContentTypeRestrictedFileField
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
pdf_file = ContentTypeRestrictedFileField(upload_to='pdfs',
content_types=['application/pdf'],
max_upload_size=5242880,
)
def convert_to_png(self, width=0, height=0):
self.__convert_to_img__(width, height, 'png')
def convert_to_jpg(self, width=0, height=0):
self.__convert_to_img__(width, height, 'jpg')
def __convert_to_img__(self, width, height, format='jpg'):
size = ''
if width and height:
size = '_' + str(width) + 'x' + str(height) + 'px'
filename = self.pdf_file.name
filepath = settings.MEDIA_ROOT + '/' + filename
output_dir = filepath + '_' + format + size + '/'
os.mkdir(output_dir)
def publish(self):
self.published_date = datetime.datetime.now()
self.save()
def __str__(self):
return ('<%s => %s: %s, %s>'%(self.__class__.__name__, self.author, self.title, self.text, self.created_date, self.published_date, self.pdf_file))
forms.py
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = ('title', 'text', 'pdf_file')
def __init__(self, *args, **kwargs):
super(Post,self).__init__(*args, **kwargs)
views.py
from django.shortcuts import redirect
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Post
from .forms import PostForm
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.pdf_file=PdfFile(pdf_file = request.FILES['pdf_file'])
post.save()
# convert to jpg file after uploading
# if you don't pass parameters then the images
# will have the actual size
post.convert_to_jpg()
# convert to png file after uploading
# if you need to resize the image just call specify it's size
# like new_pdf.convert_to_png(200, 400)
# will return 200x400 px image
post.convert_to_png(200, 400)
return redirect('post_detail', pk=post.pk)
else:
return render(request, 'blog/post_edit.html', {'form': form})
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('post_detail', pk=post.pk)
else:
return render(request, 'blog/post_edit.html', {'form': form})
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post':post})
extra.py
from django.db.models import FileField
from django.forms import Form
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _
class ContentTypeRestrictedFileField(FileField):
"""
Same as FileField, but you can specify:
* content_types - list containing allowed content_types. Example: ['application/pdf', 'image/jpeg']
* max_upload_size - a number indicating the maximum file size allowed for upload.
2.5MB - 2621440
5MB - 5242880
10MB - 10485760
20MB - 20971520
50MB - 5242880
100MB 104857600
250MB - 214958080
500MB - 429916160
"""
def __init__(self, *args, **kwargs):
self.content_types = kwargs.pop("content_types")
self.max_upload_size = kwargs.pop("max_upload_size")
super(ContentTypeRestrictedFileField, self).__init__(*args, **kwargs)
def clean(self, *args, **kwargs):
data = super(ContentTypeRestrictedFileField, self).clean(*args, **kwargs)
file = data.file
try:
content_type = file.content_type
if content_type in self.content_types:
if file._size > self.max_upload_size:
raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(self.max_upload_size), filesizeformat(file._size)))
else:
raise forms.ValidationError(_('Filetype not supported.'))
except AttributeError:
pass
return data
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="date">
{% if post.published_date %}
{{ post.published_date }}
{% endif %}
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
</div>
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
<p>>{% post.pdf_file %}</p
{% endblock %}