Skip to content

Commit 1fa0992

Browse files
committed
test project
1 parent 2acc52f commit 1fa0992

File tree

11 files changed

+375
-3
lines changed

11 files changed

+375
-3
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.swp
33
*.egg-info
44
dist/
5+
db.sqlite3

django_xhtml2pdf/utils.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
from xhtml2pdf import pisa # TODO: Change this when the lib changes.
88

99
try:
10-
from StringIO import StringIO
10+
from StringIO import StringIO, BytesIO
1111
except:
12-
from io import StringIO
12+
from io import StringIO, BytesIO
1313

1414
import os
1515

@@ -87,7 +87,7 @@ def render_to_pdf_response(template_name, context=None, pdfname=None, link_callb
8787
class PdfResponse(TemplateResponse):
8888
def render(self):
8989
retval = super(PdfResponse, self).render()
90-
result = StringIO()
90+
result = BytesIO()
9191
pisa.CreatePDF(
9292
self.rendered_content,
9393
dest=result,

test/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
How to run test
2+
=================
3+
4+
Install dependencies:
5+
6+
``
7+
pip install django
8+
pip install xhtml2pdf
9+
``
10+
11+
Make migrations and one user (need for test):
12+
13+
``
14+
cd d1_11
15+
python manage.py migrate
16+
python manage.py createsuperuser
17+
``
18+
19+
Run server:
20+
21+
``
22+
python manage.py runserver
23+
``
24+
25+
Go to this urls
26+
27+
- http://localhost:8000/test_view
28+
- http://localhost:8000/test_render_response
29+
- http://localhost:8000/test_user/1
30+

test/d1_11/__init__.py

Whitespace-only changes.

test/d1_11/manage.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env python
2+
import os
3+
import sys
4+
5+
if __name__ == "__main__":
6+
sys.path.append("../../")
7+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
8+
try:
9+
from django.core.management import execute_from_command_line
10+
except ImportError:
11+
# The above import may fail for some other reason. Ensure that the
12+
# issue is really that Django is missing to avoid masking other
13+
# exceptions on Python 2.
14+
try:
15+
import django
16+
except ImportError:
17+
raise ImportError(
18+
"Couldn't import Django. Are you sure it's installed and "
19+
"available on your PYTHONPATH environment variable? Did you "
20+
"forget to activate a virtual environment?"
21+
)
22+
raise
23+
execute_from_command_line(sys.argv)

test/d1_11/settings.py

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""
2+
Django settings for test2_11 project.
3+
4+
Generated by 'django-admin startproject' using Django 1.11.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/1.11/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/1.11/ref/settings/
11+
"""
12+
13+
import os
14+
15+
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17+
18+
19+
# Quick-start development settings - unsuitable for production
20+
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
21+
22+
# SECURITY WARNING: keep the secret key used in production secret!
23+
SECRET_KEY = '@lcd6_7zhcfgr80euylvan5mo4kl9^9q6e^qhykgom-otp8c2='
24+
25+
# SECURITY WARNING: don't run with debug turned on in production!
26+
DEBUG = True
27+
28+
ALLOWED_HOSTS = []
29+
30+
31+
# Application definition
32+
33+
INSTALLED_APPS = [
34+
'django.contrib.admin',
35+
'django.contrib.auth',
36+
'django.contrib.contenttypes',
37+
'django.contrib.sessions',
38+
'django.contrib.messages',
39+
'django.contrib.staticfiles',
40+
'django_xhtml2pdf'
41+
]
42+
43+
MIDDLEWARE = [
44+
'django.middleware.security.SecurityMiddleware',
45+
'django.contrib.sessions.middleware.SessionMiddleware',
46+
'django.middleware.common.CommonMiddleware',
47+
'django.middleware.csrf.CsrfViewMiddleware',
48+
'django.contrib.auth.middleware.AuthenticationMiddleware',
49+
'django.contrib.messages.middleware.MessageMiddleware',
50+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
51+
]
52+
53+
ROOT_URLCONF = 'urls'
54+
55+
TEMPLATES = [
56+
{
57+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
58+
'DIRS': [os.path.join(BASE_DIR, 'd1_11/templates/')],
59+
'APP_DIRS': True,
60+
'OPTIONS': {
61+
'context_processors': [
62+
'django.template.context_processors.debug',
63+
'django.template.context_processors.request',
64+
'django.contrib.auth.context_processors.auth',
65+
'django.contrib.messages.context_processors.messages',
66+
],
67+
},
68+
},
69+
]
70+
71+
WSGI_APPLICATION = 'wsgi.application'
72+
73+
74+
# Database
75+
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
76+
77+
DATABASES = {
78+
'default': {
79+
'ENGINE': 'django.db.backends.sqlite3',
80+
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
81+
}
82+
}
83+
84+
85+
# Password validation
86+
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
87+
88+
AUTH_PASSWORD_VALIDATORS = [
89+
{
90+
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
91+
},
92+
{
93+
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94+
},
95+
{
96+
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97+
},
98+
{
99+
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100+
},
101+
]
102+
103+
104+
# Internationalization
105+
# https://docs.djangoproject.com/en/1.11/topics/i18n/
106+
107+
LANGUAGE_CODE = 'en-us'
108+
109+
TIME_ZONE = 'UTC'
110+
111+
USE_I18N = True
112+
113+
USE_L10N = True
114+
115+
USE_TZ = True
116+
117+
118+
# Static files (CSS, JavaScript, Images)
119+
# https://docs.djangoproject.com/en/1.11/howto/static-files/
120+
121+
STATIC_URL = '/static/'
122+
MEDIA_URL = '/media/'
123+
124+
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
125+
STATIC_MEDIA = os.path.join(BASE_DIR, 'media/')

test/d1_11/templates/user_pdf.html

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<!--
2+
This is intended to be rendered to a PDF using pisa, not in a browser.
3+
Therefore, the HTML and CSS here can look a bit fishy. Please refer to
4+
http://www.htmltopdf.org/doc/pisa-en.html for reference
5+
-->
6+
<html>
7+
<style>
8+
/*Custom fonts*/
9+
/*@font-face {
10+
font-family: Weird, "Weird Font";
11+
src: url(test/weird.ttf)
12+
}
13+
@font-face {
14+
font-family: Akkurat;
15+
src: url(test/Akkurat.ttf)
16+
}
17+
@font-face {
18+
font-family: Akk;
19+
src: url(test/akk.otf)
20+
}*/
21+
/* Page layout */
22+
@page {
23+
@frame {
24+
-pdf-frame-content: company_logo;
25+
/*-pdf-frame-border: 1;*/
26+
right: 3cm;
27+
width: 5cm;
28+
top: 1cm;
29+
height: 1cm;
30+
}
31+
@frame {
32+
-pdf-frame-content: address_sender;
33+
/*-pdf-frame-border: 1;*/
34+
right: 4cm;
35+
width: 5cm;
36+
top: 4cm;
37+
height: 3cm;
38+
}
39+
@frame {
40+
-pdf-frame-content: address_receiver;
41+
/*-pdf-frame-border: 1;*/
42+
left: 2cm;
43+
width: 5cm;
44+
top: 4cm;
45+
height: 3cm;
46+
}
47+
@frame {
48+
-pdf-frame-content: main_text;
49+
/*-pdf-frame-border: 1;*/
50+
right: 2cm;
51+
left: 2cm;
52+
top: 7cm;
53+
bottom: 5cm;
54+
}
55+
@frame {
56+
-pdf-frame-content: signature_left;
57+
/*-pdf-frame-border: 1;*/
58+
left: 2cm;
59+
width: 5cm;
60+
bottom: 1cm;
61+
height: 3cm;
62+
}
63+
@frame {
64+
-pdf-frame-content: signature_right;
65+
/*-pdf-frame-border: 1;*/
66+
right: 2cm;
67+
width: 5cm;
68+
bottom: 1cm;
69+
height: 3cm;
70+
}
71+
}
72+
73+
h1, h2, h3, h4 { /* Don't add an outline to the document */
74+
-pdf-outline: false;
75+
}
76+
77+
.border {
78+
border-top-width: 1px;
79+
border-bottom-width: 1px;
80+
border-left-width: 1px;
81+
border-right-width: 1px;
82+
83+
border-top-style: solid;
84+
border-bottom-style: solid;
85+
border-left-style: solid;
86+
border-right-style: solid;
87+
}
88+
89+
.top_image {
90+
zoom: 80%;
91+
}
92+
93+
</style>
94+
<body>
95+
<div id="company_logo">
96+
<img src='test/logo_main.png' class="top_image" />
97+
</div>
98+
<div id="address_sender" class="compact">
99+
Test Inc.<br />
100+
Test street 1<br />
101+
CH-8022 Zürich<br />
102+
Whatever<br />
103+
</div>
104+
<div id="address_receiver" class="compact">
105+
Line 1<br />
106+
Line 2<br />
107+
Line 3<br />
108+
Line 4<br />
109+
</div>
110+
<div id="main_text">
111+
<h1>{{object.username}}</h1>
112+
<div>
113+
<h3> Whatever </h3>
114+
<!-- cannot make borders span several p tags.... -->
115+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi pretium dignissim eros, posuere venenatis purus varius vitae. Suspendisse quis elit ligula. Cras vulputate metus vitae lectus iaculis nec adipiscing est fermentum. Praesent ac urna ante. Cras semper malesuada sapien at consectetur. Vivamus arcu sapien, dignissim sit amet mollis quis, scelerisque nec nibh. In hac habitasse platea dictumst. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam rutrum interdum felis, quis suscipit justo malesuada at. Mauris luctus justo id nulla placerat et pharetra mi interdum. Mauris rhoncus augue eu tortor luctus convallis. Nulla facilisi. Morbi ut arcu enim. Nullam in leo arcu, sed ultrices felis. Etiam scelerisque rhoncus ultrices. Nulla in elit ut dolor luctus semper. In eleifend consectetur eros, et pellentesque nulla vehicula non. Nam nec lorem ut dui pellentesque dapibus. Etiam condimentum vulputate lectus.</p>
116+
<p>Fusce tempus ullamcorper magna, vitae placerat ligula convallis eget. Phasellus sed ullamcorper felis. Vivamus sit amet purus eu mi pretium tempus. Aenean tristique purus id justo suscipit fringilla. Nam egestas felis non velit luctus volutpat. Aliquam interdum congue elementum. Mauris pulvinar fermentum nisl at dignissim. Ut ornare, dolor vitae consectetur iaculis, augue diam porttitor dolor, ut lobortis lorem sem a tellus. Praesent blandit sem in arcu hendrerit ornare. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin non nibh nulla, sed lacinia ante. In viverra congue sapien, ut aliquet justo sagittis vitae. Morbi dictum venenatis eros, et pulvinar enim pretium eu.</p>
117+
</div>
118+
<div>
119+
<p>Etiam metus nisl, porttitor et convallis sit amet, imperdiet non lectus. Nam nec tincidunt nibh. Nullam dignissim lacus nec nisi adipiscing id euismod nunc pretium. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris in velit risus. Nulla vulputate vehicula diam, eu porta dolor mattis id. Pellentesque sed lacus non erat pharetra dignissim. Aenean lorem tellus, volutpat vitae aliquet ac, imperdiet at risus. Etiam condimentum, quam tempor porttitor bibendum, metus magna hendrerit turpis, ac dapibus nisl leo id massa. In a nisi ante, id mollis ligula. Sed ante erat, ultricies id lacinia sit amet, sollicitudin nec eros. Phasellus sem elit, lobortis pharetra ullamcorper tempor, volutpat sed lorem. Donec sed suscipit velit. Integer tincidunt adipiscing enim, vitae placerat urna venenatis nec.</p>
120+
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris nec nulla lorem. Sed cursus erat in dui mollis lobortis. Fusce interdum facilisis risus, sed pretium ligula suscipit vel. Duis tincidunt cursus ipsum et tristique. Sed placerat hendrerit pretium. Vestibulum porttitor porttitor faucibus. Aliquam erat volutpat. Nam elementum leo eu ante fringilla cursus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam eleifend odio a magna hendrerit congue. Sed in fermentum ligula. Maecenas interdum, velit ut bibendum sollicitudin, magna mauris cursus ligula, in condimentum neque nisl vitae dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec vel dignissim felis. Aenean vitae orci eu lacus ornare tristique eu nec neque. Etiam eleifend interdum mollis. Morbi id risus est, in vehicula nisi.</p>
121+
<p>Nunc vestibulum, lacus quis euismod posuere, nibh enim commodo tortor, eget suscipit sapien mauris quis tortor. Curabitur arcu velit, placerat non consectetur non, tristique in erat. Aliquam sagittis rhoncus mollis. In vitae tortor sapien. Pellentesque ac augue ullamcorper eros fringilla vehicula. Donec lectus urna, sodales quis sollicitudin vitae, bibendum nec ante. Etiam tortor enim, pretium in pulvinar vel, tincidunt non mauris. Nullam leo elit, varius eu pretium at, adipiscing sit amet sapien. Mauris aliquet, augue id sollicitudin viverra, nunc neque gravida arcu, ut pharetra lacus nibh quis lacus. Sed imperdiet rhoncus sapien eu accumsan. Pellentesque nec mi id mauris consequat placerat. Nunc tempus tristique justo sit amet sollicitudin. Phasellus accumsan, tellus sit amet dictum ultricies, dui nulla fermentum eros, quis venenatis sapien leo sit amet est. Sed et turpis justo. Fusce eget tellus sollicitudin sem elementum tempor. Aliquam ac nisi justo, vulputate feugiat leo. Phasellus non nulla ullamcorper arcu laoreet ornare. Suspendisse tristique volutpat auctor. </p>
122+
</div>
123+
</div>
124+
<div id="signature_right">
125+
<h1>Signature right</h1>
126+
</div>
127+
<div id="signature_left">
128+
<h1><pdf:barcode value="abc-1234-5678" type="code126" humanreadable="1" align="baseline" /></h1>
129+
</div>
130+
</body>
131+
</html>

test/d1_11/urls.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""test2_11 URL Configuration
2+
3+
The `urlpatterns` list routes URLs to views. For more information please see:
4+
https://docs.djangoproject.com/en/1.11/topics/http/urls/
5+
Examples:
6+
Function views
7+
1. Add an import: from my_app import views
8+
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9+
Class-based views
10+
1. Add an import: from other_app.views import Home
11+
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12+
Including another URLconf
13+
1. Import the include() function: from django.conf.urls import url, include
14+
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15+
"""
16+
from django.conf.urls import url
17+
from django.contrib import admin
18+
from views import test_view, test_render_response, UserPdfView
19+
20+
21+
urlpatterns = [
22+
url(r'^admin/', admin.site.urls),
23+
url(r'^test_view$', test_view),
24+
url(r'^test_render_response$', test_render_response),
25+
url(r'^test_user/(?P<pk>\d+)$', UserPdfView.as_view())
26+
]
27+

test/d1_11/views.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from django.http import HttpResponse
2+
3+
from django.views.generic.detail import DetailView
4+
from django_xhtml2pdf.views import PdfMixin
5+
from django_xhtml2pdf.utils import generate_pdf, render_to_pdf_response
6+
from django.contrib.auth.models import User
7+
8+
def test_view(request):
9+
resp = HttpResponse(content_type='application/pdf')
10+
result = generate_pdf('test_pdf.html', file_object=resp)
11+
return result
12+
13+
14+
def test_render_response(request):
15+
return render_to_pdf_response('test_pdf.html')
16+
17+
class UserPdfView(PdfMixin, DetailView):
18+
model = User
19+
template_name = "user_pdf.html"

0 commit comments

Comments
 (0)