Wykład 8: Django szczegóły
Andrzej Krajka
Django –przykłady
http://www.djangosites.org/most-comments/
Django – aplikacje flatpages
1. Utwórz nowy projekt Django przy użyciu django- admin.py
2. Otwórz settings.py i dołącz do krotki MIDDLEWARE_CLASSES:
django.contrib.flatpages.middleware.FlatpageFallbackMiddleware 3. Dodaj do INSTALLED_APPS w settings.py
django.contrib.flatpages django.contrib.admin
4. Ustaw parametry bazy danych i uruchom
manage.py syncdb aby utworzyć niezbędne tabele
5. Odblokuj panel Admina
6. Zrestartuj serwer
Django – aplikacje flatpages
Django – aplikacje flatpages
Django – aplikacje flatpages
Django – aplikacje flatpages
W templates\flatpages\default.html zapisz domyślny zablon wszystkich stron flatpages:
<html>
<head>
<title> Testowanie flatpage: {{ flatpage.title }}</title>
</head>
<body>
<h1>{{ flatpage.title }}</h1>
<p>{{ flatpage.content }}</p>
</body>
</html>
Natomiast w settings.py:
TEMPLATE_DIRS = (
"C:/Django/pr1/templates",
)
Django – aplikacje flatpages
Django – AJAX
AJAX
(ang. Asynchronous JavaScript and XML, asynchroniczny JavaScript i XML) – technologia tworzenia aplikacji internetowych, w której interakcja użytkownika z serwerem odbywa się bez przeładowywania całego dokumentu, w sposóbasynchroniczny. Ma to umożliwiać bardziej dynamiczną interakcję z użytkownikiem niż w tradycyjnym modelu, w którym każde żądanie nowych danych wiąże się z przesłaniem całej strony HTML.
Elementy AJAXa
XMLHttpRequest - klasa umożliwiająca asynchroniczne przesyłanie danych; dzięki asynchroniczności w trakcie pobierania danych użytkownik może wykonywać inne czynności, można także pobierać dane jednocześnie z wielu miejsc.
JavaScript - mimo użycia w nazwie, może to być de facto dowolny język skryptowy funkcjonujący po stronie użytkownika (np. JScript czy VBScript).
XML - język znaczników, poprzez który miałyby być opisane odbierane informacje. W praktyce jednak dane często przekazywane są w innym formacie, przy czym
odbierane są wtedy jako tekst. Mogą to być zarówno gotowe fragmenty HTML, jak i fragmenty kodu JavaScript (zob. JSON), może to być też format specyficzny dla danego zastosowania.
Django – AJAX
Biblioteki AJAXowe
Dojo, jQuery, MochiKit, MooTools, Prototype, YUI (Yahoo User Interface)
Implementacja AJAXa
Zaimportowanie biblioteki aby móc ja wykorzystać w szablonie
Zdefiniowanie funkcji zwrotnej po stronie klienta (korzystając z biblioteki)
Utworzenie logiki po stronie serwera
Kroki AJAXa
http://jquery.com http://www.dynamicdrive.com/dynamicindex17/ajaxroutine.htm 1. Pobierz bibliotekę ajaxroutine.js i umieść w katalogu /media/js
2. W widoku:
def ajax(request):
return HttpResponse(unicode(datetime.now()) 3. W urls.py
(r’^ajax/$’, ‘prog.views.ajax’), 4. W szablonie base.html w sekcji head:
<script type=„text/javascript” src=„/site_media/ajaxroutine.js”></script>
<script type=„text/javascript”>
Function processGetPost() {
var myajax=ajaxpack.ajaxobj var myfiletype=ajaxpack.filetype if (myajax.readyState == 4)
{ if (myajax.status==200 || window.location.href.indexOf(„http”)==-1) {
// Jeśli zostanie coś zwrócone pokaż to if (myajax.responseText.length>3)
{ document.getElementById(‘aj’).innerHTML-’<h1>’ + myajax.responseText + ‘</h1>’; } else
{ // Wyczyścimy komunikat
Document.getElementById(‘aj’).InnerHTML=‘’; } } } } </script>
Django – AJAX
5. W kodzie szablonu dopisz
<div id=„aj” style=„text-align:center;”></div>
<a herf=„#” onclick=ajaxpack.getAjaxRequest
(‘/ajax/’. ’’.processGetPost.’txt’)”>Czas przez AJAX</a>
processGetPost – funkcja wstawiająca otrzymane dane do taga DIV o ID aj
Odsyłacz: CZAS PRZEZ AJAX będzie wysyłał żadania AJAXa za pomocą biblioteki ajaxroutine
DJANGO – dostosowywanie Panelu Admina
Obiekt fieldset class Person …
class PersonAdmin (Admin.ModelAdmin):
fieldsets=[(„Name”m {„fields”, ”firstname”, „lastname”)}), („Location”, {„fields”:{„city”, „state”)}) ]
Admin.site.register(Person, PersonAdmin) 2. Zmiana szablonu panelu ADMINA
C:\Python27\Lib\site-packages\django\contrib\admin\templates\admin 404.Html 500.html actions.html app_index.html base.html
base_site.html change_form.html change_list.html change_list_results.html date_hierarchy.html delete_confirmation.html delete_selected_confirmation.html filter.html index.html invalid_setup.html login.html object_history.html pagination.html prepopulated_fields_js.html search_form.html submit_line.html
INSTALLED_APPS ‘django.contrib.admin’
3. Dodawanie widoków i uwierzytelnianie za pomocą dekoratorów
DJANGO – sitemaps
Sitemap to plik XML zawierający listę stron serwisu (wynalezione przez GOOGLE).
Przykład:
1. W settings.py do INSTALLED_APPS dodaj ‘ django.contrib.sitemaps’,
2. W feeds.py dodaj kod
from django.contrib.sitemaps import Sitemap class NewMap(Sitemap):
def items(self):
return Paste.objects.all() def lastmod( self.obj ):
return obj.date
def changefreq( self.obj ):
return ‘monthly’
3. W urls.py dopisz
sitemaps= { ‘news’: NewMap, } 4. Reguła mapowania
(r’^sitemap.xml$’, ‘django.contrib.sitemaps.views.sitemap’, {‘sitemaps’:sitemaps})
Pod adresem http://localhost:8000/sitemap.xml mapa
DJANGO – Kanały RSS
RSS – umowna rodzina języków znacznikowych do przesyłania nagłówków wiadomości i nowości na wybranych przez użytkownika RSS stronach. Wystarczy dodać daną stronę (musi ona obsługiwać system RSS) do czytnika RSS. Wszystkie w większym lub mniejszym zakresie bazują na XML-u.
Aby skorzystać z kanału RSS, potrzebny jest odpowiedni program, tzw. czytnik kanałów. Często czytniki RSS-ów są zamieszczane w programach pocztowych. Wyróżnia się następujące rodziny RSS:
RDF Site Summary (RSS 1.x, RSS 0.90)
Rich Site Summary (RSS 0.91/RSS 0.92/RSS 0.93)
Robust Site Syndication (RSS 0.99)
Really Simple Syndication (RSS 2.0) Wiadomości RSS można przeglądać w:
specjalnych programach do odczytu wiadomości RSS (w tym również wielu programach pocztowych)
serwisach internetowych
przeglądarkach internetowych: Avant Browser, Flock, Internet Explorer 7 i 8, K-Meleon, Maxthon, Mozilla Firefox, Opera oraz Safari.
Nie wszystkie popularne przeglądarki potrafią jednak wyświetlać RSS. Przykładowo Google Chrome nie obsługuje kanałów RSS, wyświetlając tekst źródła pliku XML.
Tworzenie kanałów RSS (lub ATOM) w DJANGO za pomocą FEED polega na zdefiniowaniu klasy
zawierającej opis kanału (title, link, description) oraz podklasy items określającej listę rekordów do wyświetlenia. Dodatkowo można podac proste szablony określające jakie pola modelu należy wyświetlić dla pól title i description w kanale RSS
DJANGO – Kanały RSS
Plik feeds.py:
from … models import *
from django.contrib.syndication.feeds import Feed
class LatestPaste(Feed):
title=„Wiadomość z localhost:8000”
link=„localhost:8000”
description=„Przesyłam następny fragment programu…”
def items(self):
return Paste.objects.order_by(‘-id’)[:15]
Plik urls.py
from … feeds import *
feeds={‘news’: LatestPaste,}
Reguła mapowania w urls.py
(r’^rss/(?P<ur>.*)/$’, ‘django.contrib.syndication.views.feed’, {‘feed_dict’:feeds})
W katalogu templates utwórz pliki news_title.html o kodzie
{{ obj.title }}
i news_description.html o kodzie
{{ obj text|safe }}
Pod adresem http://localhost:8000/rss/news kanał RSS
DJANGO - PyCha
• Strona domowa: https://bitbucket.org/lgs/pycha/wiki/Home
• Dokumentacja: http://packages.python.org/pycha/
• Bar charts, Pie charts, Line charts
DJANGO - PyCha
Rodzaje kart (cd)
Pie Charts
pycha.pie.PieChart
Bar Charts
pycha.bar.VerticalBarChart pycha.bar.HorizontalBarChart
Line Charts
pycha.bar.LineChart
Scatterplot Charts
pycha.scatter.ScatterplotChart
Stacked Bar Charts
pycha.stackedbar.StackedVerticalBarChart
pycha.stackedbar.StackedHorizontalBarChart
DJANGO - PyCha
Utwórz obiekt surface systemu Cairo (główny komponent rysowania) import cairo
width, height = (500, 400)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
Utwórz listę danych z których karta będzie rysowana dataSet = ( ('dataSet 1', ((0, 1), (1, 3), (2, 2.5))),
('dataSet 2', ((0, 2), (1, 4), (2, 3))), ('dataSet 3', ((0, 5), (1, 1), (2, 0.5))), )
Przygotuj parametry karty
options = { 'legend': {'hide': True}, 'background': {'color': '#f0f0f0'}, }
Utwórz kartę, dodaj zbiór danych i zrenderuj go import pycha.bar
chart = pycha.bar.VerticalBarChart(surface, options) chart.addDataset(dataSet)
chart.render()
Zapisz wynik w zbiorze lub jeśli chcesz z obiektem surface Cairo surface.write_to_png('output.png')
DJANGO - PyCha
def pie_chart(request):
import cairo , sys, pycha.pie
data = ((‘chrzescijanie’, 35), (‘muzulmanie’,47), (‘buddysci’,13), (‘hinduisci’, 5),) dataset=[(item[0], [[0, item[1]]]) for item in data]
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 750, 450) ticks =[dict(v=i, label=d[0]) for i,d in enumerate(data)]
options = { 'legend': {'hide': True}, 'background': {'color': '#f0f0f0'}, ‘axis’:
{‘ticks’:ticks}}
chart = pycha.pie.PieChart(surface, options) chart.addDataset(dataset)
chart.render()
response = HttpResponse(mimetype=„image/png”) surface.write_to_png(response)
response[‘Content-Disposition’]=‘attachment; filename=pie.png’
return response
Zapisz wynik w zbiorze lub jeśli chcesz z obiektem surface Cairo surface.write_to_png('output.png')
Django – własne filtry
Szablon:
{% load randomizers %}
<img src={% random_image „faces/thumbnails” %}” />
Kod w katalogu templatetags (__init__.py) :
import os, random, posixpath # posixpath jak os w UNIX from django import template
from django.conf import settings register=template.Library()
# dostęp do dekoratorów w obiekcie template
def files(path, types=[„.jpg”, „.jpeg”, „.png”, „.gif”]):
# lista nazw plików
fullpath=os.path.join(settings.MEDIA_ROOT, path)
return [f for f in os.listdir(fullpath) if os.path.splitext(f)[1] in types]
# dołączenie do listy znaczników
@register.simple_tag
def random_image(path):
pick=random.choice(files(path))
return posixpath.join(settings.MEDIA_URL, path, pick)
Django –filtry dołączania
Szablon:
{% load inclusion_tags %}
{% calendar_table %}” />
Kod w katalogu templatetags (__init__.py) :
@register.inclusion_tag(„_calendar.html”) def calendar_table():
import calendar, datetime date = datetime.date,today()
month=calendar.monthcalendar(date.year, date.month) weeks=[[day or ‘’ for day in week] for week in month]
return { ‘month’: calendar.month_name[date.month], ‘year’: date.year, ‘weeks’:weeks, ‘daynames’:
calemdar.day_abbr,}
Plik _calendar.html:
<style type=„text/css”>
td, th { padding: 4px; width: 30px; backgground: #bbb; } td { text-align: right; }
</style>
<table>
<tr><th colspan=‘7’>{{ month }} {{ year }} </th></tr>
<tr>{% for dayname in daynames %}<th>{{ dayname }}</tr>{% endfor %}</tr>
{% for week in weeks %}
<tr>
{% for day in week %}
<td>{{ day }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
Django – znaczniki szablonów CACHE
{% load cache %}
… niebuforowany
{% cache 300 list_of_stuff LANGUAGE_CODE %}
{% for item in bardzo_dluga_lista %}
{{ item.wykonaj_kosztowne_renderowanie }}
{% endfor %}
{% endcache %}
… niebuforowane
Buforowanie po stronie serwera:
dummy – tylko w trakcie projektowania
locmem – dane przechowywane w pamięci file – buforowanie przy użyciu plików
db – buforowanie przy użyciu bazy danych
memcached – wysokowydajny rozproszony system buforowania
Django – PDF
http://www.reportlab.org/rl_toolkit.html
ReportLab – techniczne narzędzie służące do generowania raportów, zestawień czy innych dokumentów
Pisa – konwersja kodu HTML na PDF (wymaga:
Reportlab Toolkit 2.1+, html5lib; a opcjonalnie:PIL i pyPDF)
Etapy w reportlabie:
1. Określenie płótna (canvas) czyli rozmiaru strony i nazwy pliku
2. Zarejestrowanie czcinki (np. dejavusans.ttf) 3. W reportlabie elementy sa umieszczane
(rysowane) w miejscu (x,y) określonym w pikselach 4. Do wyświetlania tekstu stosujemy nieformatowany
(drawString) i formatowany (Paragraph)
Django – PDF
from reportlab.platypus import Table, TableStyle, Paragraph from reportlab.lib import colors
from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.styles import getSampleStyleSheet def showpdf(request,slug):
en=Paste.objects.filter(id=slug) for f in en:
ent=f.content entd=f.timestamp e=HttpResponse()
e['Content-Type']='application/pdf'
e['Content-Disposition']='attachment: filename="%s.pdf";' % slug c=canvas.Canvas(e, pagesize=A4)
width, height = A4
pdfmetrics.registerFont(TTFont('Dejavu','C:/Django/osoba/media/DejaVuSans.ttf')) c.setFont("Dejavu",14)
c.drawString(50, (height-60), ent) stylesheet=getSampleStyleSheet() styleN=stylesheet['Normal']
styleN.fontName = 'Dejavu' styleN.fontSize=9
p=Paragraph(ent, styleN) w,h=p.wrap(width-70, height) p.drawOn(c, 50, (height-120)) c.line(50, (70), 570, (70)) c.setFont("Dejavu",8)
c.drawString(50,(60),unicode(entd)) c.showPage()
c.save() return e