Django nutshell overview
-
Upload
schacki -
Category
Technology
-
view
413 -
download
1
description
Transcript of Django nutshell overview
Django in a Nutshell
Python User Group München - µPy 6. November 2012
© Juergen Schackmann 2012
© Juergen Schackmann 2012 2/69
Ziel
▸ Überblick über Django
▸ Besprechung wesentlicher Komponenten
▸ Customizing Möglichkeiten
▸ Django Ökosystem
▸ Bewertung
▸ Kein Django Tutorial
▸ Kein hands-on workshop (gerne als separater Termin)
© Juergen Schackmann 2012 3/69
Agenda
▸ Übersicht
▸ Quick Start
▸ Project und (pluggable) Apps
▸ Wesentlich Django Komponenten
▸ Admin
▸ Settings
▸ Room for Improvement
Übersicht
© Juergen Schackmann 2012 5/69
Was ist Django (nicht)
▸ Web application Framework
▸ Pure Python
▸ Full-Stack (keine bzw. kaum externe dependencies)
▸ Philosophie:
▸ Dry
▸ Loose Coupling
▸ MVC bzw. MVT
▸ BSD Lizenz
▸ Django Software Foundation
▸ Sehr gute Dokumentation und große freundliche Community
▸ Django ist kein Content Management System (aber es gibt in Django implementierte CMS)
Quellen: django-workshop.de/einfuehrung.html, djangobook.com/en/2.0/chapter01.html
© Juergen Schackmann 2012 6/69
Historie
▸ Entstanden 2003/2004 bei lawrence.com (Medienunternehmen, Zeitung) als closed source in Kansas (ebenso wie memcache)
▸ Benannt nach Django Reinhardt (Jazz Guitarist)
▸ Open Source: 2005
▸ “Benevolent Dictators for Life”: Jacob Kaplan-Moss, Adrian Holovaty
▸ Ursprung aus der Medienindustrie hat die Use Cases und Sweet Spots geprägt
▸ Aktuelle stabile Version: 1.4.2
▸ Version 1.5 bringt Python 3 Unterstützung
▸ Minor Release alle 9 Monate
Quellen: http://www.quora.com/What-is-the-history-of-the-Django-web-framework,http://www.djangobook.com/en/2.0/chapter01.html
© Juergen Schackmann 2012 7/69
Django Ressourcen
▸ Homepage: djangoproject.com
▸ Docs: docs.djangoproject.com/en/1.4/
▸ Code: github.com/django/django
▸ User Mailing List: groups.google.com/forum/?fromgroups#!forum/django-users
▸ Django App Ökosystem: djangopackages.com
▸ Django powered Websites: djangosites.org
▸ Django Snipptes: djangosnippets.org
© Juergen Schackmann 2012 8/69
Bücher, Tutorials, Trainings, ...
▸ Tutorial: docs.djangoproject.com/en/1.4/intro/tutorial01/
▸ Django Workshop (deutsch): django-workshop.de
▸ Django Book: djangobook.com/en/2.0/index.html
▸ amazon.de/Pro-Django-Experts-Voice-Development/dp/1430210478
▸ amazon.de/Python-Development-Django-Developers-Library/dp/0132356139
© Juergen Schackmann 2012 9/69
Videos
▸ Serie von Django Video Tutorials (für Anfänger):hackedexistence.com/project-django.html
▸ Video: Django Blog in 30 min (für Fortschreitende): http://arunrocks.com/blog/2012/03/05/building_a_blog_in_30_mins_with_django_%28screencast%2
▸ Django in Depth, sehr gute 3h presentation (nichts für Anfänger): youtube.com/watch?v=t_ziKY1ayCo
© Juergen Schackmann 2012 10/69
Bekannte Django Sites
bitbucket.org
instagram.com disqus.com
nytimes.com
washingtonpost.com
pinterest.com
ubuntuusers.de
turnkeylinux.org
Quick-Start
© Juergen Schackmann 2012 12/69
Quick Start
1. Django Installation
2. Projekt erzeugen
3. Development Web Server starten
4. App(s) erzeugen
5. Datenbank Schema erzeugen
© Juergen Schackmann 2012 13/69
Installation
==> Done :-)
▸ 7,7 MB download vom PyPi
▸ keine weiteren Dependencies
▸ Tip: am besten Installation in ein Virtualenv
>>> pip install django
© Juergen Schackmann 2012 14/69
Projekt erzeugen
Django kommt mit Kommandozeilen Tool zur Erzeugung und Verwaltung von Projekten und Apps
>>> django-admin startproject nutshell>>> cd nutshell
nutshell/manage.py << Tool zur Verwaltung dieses Projektsnutshell/ << Verzeichnis mit Code & Settings für dieses Projekt
__init__.pysettings.py << Konfigurations File urls.py << Url Konfigurationwsgi.py << WSGI Applikation
Erzeugt die komplette Verzeichnisstruktur mit allen relevanten Daten für ein Django Projekt
© Juergen Schackmann 2012 15/69
Django Webserver starten
>>> python manage.py runserver
Starten des Django Webservers
Und Aufruf unter http://127.0.0.1:8000/
Achtung: Django Webserver nur für Entwicklung nutzen, nicht für Produktion vorgesehen
© Juergen Schackmann 2012 16/69
App(s) erzeugen
Jedes Django Projekt besteht aus mindestens einer App (in der Regel aber aus sehr vielen Apps)
>>> python manage.py startapp nuts
nutshell/ << Rootnutshell/ << Projectnuts/ << App Verzeichnis
__init__.pymodels..py << App Modelstests.py << Unit Testsviews.py << Views (=Controllers)
Erzeugt die komplette Verzeichnisstruktur mit allen relevanten Dateien für eine Django App
Achtung: Apps müssen nicht im Project Verzeichns liegen, Python Path reicht aus
© Juergen Schackmann 2012 17/69
Datenbank Schema erzeugen
Generierung des Datenbank Schemas
>>> python manage.py syncdb
Achtung: zuerst muss in settings.py die Datenbank/ Datenbankverbindung eingetragen werden (am besten SQLite)
© Juergen Schackmann 2012 18/69
Notwendige nächste Schritte
▸ Anpassung settings.py
▸ Eintrag der Datenbank
▸ Hinzufügen gewünschter Apps
==> Happy Coding
Project und (pluggable) Apps
© Juergen Schackmann 2012 20/69
Apps im Project (Idealfall)
▸ Project definiert sich über settings.py, urls.py und Templates (Verzeichnis)
▸ Project besteht aus unabhängigen Apps
▸ Apps müssen nichts übereinander wissen
App 1
KonfigurationSettings.py
URL Routing urls.py
PresentationTemplates
App 2 App 3 App 4
© Juergen Schackmann 2012 21/69
Pluggable Apps
▸ Jede App sollte
▸ genau eine Aufgabe sehr gut erledigen
▸ eigenständig funktionieren (ohne Wissen über andere Apps)
▸ möglichst weit konfigurierbar sein
▸ idealer Weise mit eigener setup.py und upload zu pypi
▸ Beispiele für gute Apps
▸ Tagging
▸ Themes/Skins
▸ Comments
▸ Beispiele for schlechte App:
“Handle entries in a weblog, and users who post them, and their authentication, and tagging and categorization, and some flat pages for static content, and...
▸ Übersicht Django Apps: djangopackages.comQuellen: http://media.b-list.org/presentations/2008/djangocon/reusable_apps.pdf, http://www.slideshare.net/coordt/pluggable-django-application-patterns-pycon-2011
© Juergen Schackmann 2012 22/69
Typisches Project Verzeichnis
▸ Default Einstellung sind Best Practice für kleinere bis mittlere Projekte
▸ Wording ist Konvention und beliebig anpassbar
▸ Verzeichnisstruktur mein persönlicher Vorschlag und beliebig anpassbar
▸ Konvention und Struktur wird in settings.py definiert
nutshell/ << Project Rootmanage.py << Tool zur Verwaltung dieses Projects(automatisch erzeugt)site_static/ << Statische Files (wird während Deployment gefüllt)media/ << Media Files (upload files, wird während Nutzung gefüllt)nutshell/ << Verzeichnis mit Code & Settings für dieses Projekt
__init__.pysettings.py << Konfigurations File (automatisch erzeugt und erweitert))urls.py << Url Konfiguration (automatisch erzeugt und erweitert)wsgi.py << WSGI Applikation(automatisch erzeugt)templates/ << Projektspezifische Templates (überschreiben App Templates)fixtures/ << Projektspezifische Fixtures(überschreiben App Fixtures)
© Juergen Schackmann 2012 23/69
Typisches App Verzeichnis
▸ All apps müssen als Package im Python Path auffindbar sein
▸ models.py ist die einzige Anforderung von Django, kann aber auch leer sein
▸ Wording für "templatetags" und "commands" ist fix
nuts/ << App Verzeichnis__init__.pysettings.py << App spezifische Settings / Konfigurationmodels.py << App Modelstests.py << Unit Testsforms.py << Django Formulareadmin.py << Admin (Admin Seiten für ausgewählte Models)views.py << Views (=Controllers)urls.py << Urls Conf (Url mapping auf App Views)templatetags/ << Custom templatetagscommand/ << Zusätzliche manage.py. commandstemplates/ << App Templates (durch Project Templates überschreibbar)static/ << Statische App files (durch statische Project files überschreibbar)fixtures/ << App Fixtures
© Juergen Schackmann 2012 24/69
Typische Django App Liste (settings.py)
INSTALLED_APPS = ( 'django.contrib.auth', << User Management, Authentifizierung, Autorisierung 'django.contrib.contenttypes', << Dependency für folgende 'django.contrib.sessions', << Session Management 'django.contrib.sites', << Betreiben mehrere Sites aus einem Projekt 'django.contrib.messages', << Messages im Browser 'django.contrib.staticfiles', << Statische files für Entwicklung und Deployment 'django.contrib.admin', << Admin für alle apps (sehr nützlich) 'south', << Datenschema Migration 'debug_toolbar' << Debug Toolbar im Browser (für Entwicklung) 'nuts1', << Custom App 'nuts2', << Custom App)
Wesentliche Django Komponenten
(views,templates,models,forms)
© Juergen Schackmann 2012 26/69
Django Http Request (vereinfacht)
Django HTTP
Handler
Url Konfigu-raiton
View
Model
Templates
Model
Control
View
© Juergen Schackmann 2012 27/69
Model (ORM)
▸ Eigener Object-Relational-Mapper
▸ Verfügbare Backend Wrapper: SQLite, MySQL, PostgreSQL, Oracle
▸ Es werden alle wesentlichen Feldtypen unterstützt sowie 1-1, 1-n und m-n Beziehungen
▸ Datenbanktyp und Datenbankverbindung wird in settings.py definiert
▸ Initiale Erzeugung des Datenbankschemas inkl. Fixtures: manage.py syncdb
models.py
Django HTTP
Handler
Url Konfigu-raiton
View
Model
Templates
© Juergen Schackmann 2012 28/69
Einfaches Model
▸ Ausreichend für Erzeugung der Datenbankobjekte (syncdb)
▸ Verhält sich wie jede Python Class
▸ Viel __metaclass__ magic im Hintergrund
class Recipe(models.Model): title = models.CharField(verbose_name='Titel', max_length=255) preparation = models.TextField('Zubereitung', help_text='Zubereitung der Zutaten',blank=True) date_created = models.DateTimeField(editable=False) is_active = models.BooleanField('Aktiv') def __unicode__(self): return self.title
© Juergen Schackmann 2012 29/69
Models Meta
▸ In Meta können unterschiedlichste Details konfiguriert werden
▸ Übersicht über alle Meta optionen: docs.djangoproject.com/en/1.4/ref/models/options/
▸ Die vorhandenen Defaults sind aber in der Regel ausreichend
class Recipe(models.Model): ... class Meta: verbose_name = 'Rezept' verbose_name_plural = 'Rezepte' ordering = ['-date_created'] db_table = 'meine_rezepte'
© Juergen Schackmann 2012 30/69
Model Beziehungen
▸ Django unterstützt 1-1, 1-n und m-n Beziehungen
▸ Mapping Models für m-n Beziehungen werden automatisch erzeugt oder können auch explizit definiert werden
▸ Beziehungsfeld im “entfernten” Model wird automatisch angelegt
class Category(models.Model): name = models.CharField('Name', max_length=100) description = models.TextField('Beschreibung', blank=True)
class Recipe(models.Model): … categories = models.ManyToManyField(Category,related_name='recipes',verbose_name='Kategorie') author = models.ForeignKey(User, verbose_name='Autor') # User ist aus Django Contrib
© Juergen Schackmann 2012 31/69
Model Methoden
class Recipe(models.Model):
@models.permalink
def get_absolute_url(self): # Empfohlene Methode fuer alle Modelle
return ('recipes_recipe_detail', (), {'id': self.id})
def save(self, *args, **kwargs): # Ueberschreiben einer Standard Methode
if not self.id: # D.h. es handelt sich um eine neue, noch nicht gespeicherte Instanz
self.date_created = datetime.datetime.now()
super(Recipe, self).save(*args, **kwargs)
def is_tasty(self): # Erzeugen einer eigenen Methode für Recipes
return 'yes'
@property
def tasty(self): # Erzeugen einer Property
return 'yes'
© Juergen Schackmann 2012 32/69
Model Managers
▸ Jedes Model hat mindestens ein Manager object; default Name "objects"
▸ Manager besitzt alle notwendigen Methoden, um Models
▸ zu verwalten (erzeugen, löschen, etc)
▸ Datenbankqueries abzusetzen (select)
▸ Manager funktioniert nicht bei Model Instanzen, d.h. nicht um einzelne Objecte zu managen.
▸ Docs: docs.djangoproject.com/en/dev/topics/db/managers/
class Recipe(models.Model): objects = models.Manager() # Default Manager (diese Zeile könnte auch weggelassen werden) active = ActiveRecipeManager() # Custom Manager der nur aktive Rezepte zurkückliefert
© Juergen Schackmann 2012 33/69
Model QuerySets
▸ Django Abstraktion einer DB query
▸ Chainable
▸ “lazy”, d.h. Datenkbankzugriff erst dann, wenn unbedingt notwendig
▸ Benutzbar wie Python Listen
▸ Docs: docs.djangoproject.com/en/dev/ref/models/querysets/
queryset=Recipe.objects.filter(title='abc')
© Juergen Schackmann 2012 34/69
Beispiele Managers und Queries
recipe=Recipe(title='test') # Neue Recipe Instanz wird erzeugt
recipe.save() # Speicherung der neuen Instanz in Datenbank
recipes=Recipe.objects.all() # liefert ein QuerySet zurück, aber noch keine Datenbankabfrage
for recipe in recipes: # erst jetzt erfolgt die Datenbankabfrage und liefert liste zurück
....
recipes=Recipe.objects.filter(active=True) # liefert QuerySet zurueck, aber noch keine Abfrage
recipes = recipes.filter(author=user_juergen) # QuerySets lassen sich verketten
recipe_first=recipes[0] # Erst jetzt erfolgt die Abfrage
recipe = recipes.objects.get(author__name='juergen') # Beziehungen per '__', get findet genau
eine Instance oder erzeugt Fehler
recipe_first.objects.all() # Fehler, objects funktioniert nicht mit Instanzen
© Juergen Schackmann 2012 35/69
Model Vererbung
▸ Modelle können vererbt werden
▸ Im Hintergrund wird 1-1 Beziehung zwischen Parent (Recipe) und Child (PremiumRecipe) erzeugt (und automatisch verwaltet)
▸ Zu tiefe Vererbung kann deshalb zu Performanceproblemen führen
▸ Spezialfälle: abstract, proxy, managed
class Recipe(models.Model): ...
class PremiumRecipe(Recipe): price=models.FloatField()
© Juergen Schackmann 2012 36/69
Templates
▸ Eigenes Template System
▸ Kann ersetzt werden (bswp jinja)
▸ Performance: ok, aber schlechter als jinja
"the Django template system is not simply Python embedded into HTML. This is by design: the template system is meant to express presentation, not program logic."
Django HTTP
Handler
Url Konfigu-raiton
View
Model
Templates
Templates/
© Juergen Schackmann 2012 37/69
Wesentliche Template Elemente
▸ Jedes Template wird mit einem Context dict gerendert
▸ Nur Objekte aus dem übergebenen Context sind verfügbar
▸ Aus Template heraus können nur Funktionen ohne Parameter aufgerufen werden, bspw. recipe.objects.all(), aber nicht recipe.objects.filter(title='test')
▸ Direkter Aufruf von Context Objekten:
{{ user }}
▸ Tags sind komplexere Funktionen und Logik:
{% if user %} Welcome {% endif %}
▸ Filter sind Funktionen die den Input verändern:
{{ user.name|capfirst }}
© Juergen Schackmann 2012 38/69
Einfaches Beispiel
<head><title>Kochbuch</title></head>
<body>
<h1>Kochbuch</h1>
{% if user %}Welcome {{ user.name|capfirst }} {% else %} Login {% endif %}
<h2>Alle Rezepte</h2>
<ul>
{% for recipe in object_list %}
<li><a href="{{ recipe.get_absolute_url }}">{{ recipe.title }}</a></li>
{% endfor %}
</ul>
</body>
© Juergen Schackmann 2012 39/69
Template Vererbung
▸ Templates können einfach vererbt werden per "extends"
▸ Mehrfachvererbung ist nicht möglich
▸ In einem Templates können Blöcke definiert werden
▸ In einem vererbten Template können die Blöcke überschrieben oder erweitert werden
▸ Mehrfahrvererbung durch "include" simuliert
© Juergen Schackmann 2012 40/69
Beispiel Vererbung: base.html
<head>
<title>{% block title %}Kochbuch{% endblock%}</title>
</head>
<body>
<h1>Kochbuch</h1>
{% block login %} {% endblock %}
{% block content %} {% endblock %}
</body>
© Juergen Schackmann 2012 41/69
Beispiel Vererbung: recipe_list.html
{% extends "base.html" %}
{% block title %}{{ block.super }} - Alle Rezepte{% endblock %}
{% block login %} {% include "userauth/login.html" %} {% endblock %}
{% block content %}
<h2>Alle Rezepte</h2>
<ul>
{% for recipe in object_list %}
<li><a href="{{ recipe.get_absolute_url }}">{{ recipe.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
© Juergen Schackmann 2012 42/69
Templates Finder & Loader
Kein direkter Zugriff auf Template files, nur über Templates Loader (definiert in settings.py)
TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader',)
▸ Loader werden in definierter Reihenfolge abgearbeitet
▸ Erster Fund wird zurückgeliefert
▸ Default Verhalten:
▸ Suche im Project Template Verzeichnis (d.h. gecustomized für Project)
▸ Wenn nicht gefunden, suche in den App Template Verzeichnissen aller Apps (in der Reihenfolge wie in INSTALLED_APPS) und liefer ersten Fund zurück
▸ Apps können sich Templates also auch selbst überschreiben (wichtig für Skins/Themes)
© Juergen Schackmann 2012 43/69
Beispiel Finder & Loader
nuts/recipe_list.html extends extends nuts/base.html extends base.html
nutshell/ << Root
nutshell/ << Project
templates/ << Project Templates
base.html << Project Base
nuts/ << Project Nuts Templates
base.html << Projet Nuts bass
nuts/ << App Verzeichnis
templates/ << App Templates
nuts/ << App Nuts Templates Verzeichnis
base.html << App Nuts Base
recipe_list.hml
© Juergen Schackmann 2012 44/69
Views
▸ Views sind die Django Controller (MVC)
▸ View Anforderungen
▸ Callable
▸ Parameter: Django request object (plus optionale args,kwargs)
▸ Return: Django response object
▸ Typische Struktur:
▸ Bestimmung Templates
▸ Berechnung des Context objects (dict)
▸ Rendern des Templates mit Context
▸ Return des gerenderten Templates in Django Response object
Django HTTP
Handler
Url Konfigu-raiton
View
Model
Templates
views.py/
© Juergen Schackmann 2012 45/69
Einfacher View
Views können implementiert werden ohne Django ORM und Templates!
def hello(request):
return HttpResponse("<html><body>Hello World</body></html>")
© Juergen Schackmann 2012 46/69
View mit Logik und Shortcuts
def recipe_detail(request, recipe_id):
r=get_object_or_404(Recipe, pk=recipe_id)
return render(request,'recipe/recipe_detail.html', {'recipe': r})
def recipe_detail(request, recipe_id): try: r = Recipe.objects.get(pk=recipe_id) except Recipe.DoesNotExist: raise Http404 t = loader.get_template('recipe/recipe_detail.html') c = RequestContext(request, {'recipe': r}) return HttpResponse(t.render(c))
© Juergen Schackmann 2012 47/69
Class Based (Generic) Views
▸ Customizing via
▸ __init__ Parameter (ohne neue Klasse)
▸ Class Atrribute
▸ Methoden überschreiben
▸ Methoden überschreiben komplex, derzeit schwache Doku
▸ Achtung: class based views haben in UrlConf spezielle Syntax
class RecipeDetailView(DetailView):
model=Recipe
#template_name='recipe/recipe_detail.html' << default
class RecipeListView(ListView):
model=Recipe
template_name='recipe/my_recipe_list.html' << default
© Juergen Schackmann 2012 48/69
Forms
▸ Eigenes Forms Package
▸ Initialisierung aus Model
▸ Automatisches Rendern in HTML
▸ Einfaches umwandlen von Post Request zurück in Model
▸ ModelForms
▸ Dynamische Generierung aus Model
▸ Hilfreiche App: ChrispyForms github.com/maraujop/django-crispy-forms
▸ Docs: docs.djangoproject.com/en/1.4/topics/forms
© Juergen Schackmann 2012 49/69
Form Handling Beispiel
def edit(request, recipe_id):
recipe = get_object_or_404(Recipe, pk=recipe_id)
if request.method == 'POST':
form = RecipeForm(instance=recipe, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(recipe.get_absolute_url())
else:
form = RecipeForm(instance=recipe)
return render(request, 'recipes/form.html',
{'form': form, 'add': False, 'object': recipe})
© Juergen Schackmann 2012 50/69
Url Konfiguration
▸ Mapping Tuple: Regex ==> Views
▸ Tuple Name: “urlpatterns”
▸ Regex Arguments als args und kwargs für View
▸ Named Patterns mit Reverese URL Lookup
▸ App Urls pluggable in Project Urls via Include
Django HTTP
Handler
Url Konfigu-raiton
View
Model
Templates
urls.py/
© Juergen Schackmann 2012 51/69
Typische App Url Konfiguration
▸ patterns(prefix,*list)
▸ Prefix: optional, gemeinsames Package für alle views
▸ url(regex,view, kwargs,name)
▸ view: view name als string oder callable
▸ kwargs (optional): zusätzliche default Parameter
▸ name(optional): beliebiger, aber eindeutiger name
▸ Weitere Syntaxvarianten möglich; siehe docs: docs.djangoproject.com/en/1.4/topics/http/urls/
urlpatterns = patterns('recipes.views',
url(r'^erstellen/$', 'add', name='recipes_recipe_add'),
url(r'^bearbeiten/(?P<recipe_id>\d+)/$', 'edit', name='recipes_recipe_edit'),
url(r'^rezept/(?P<pk>[-\w]+)/$', RecipeDetailView.as_view(), name='recipes_recipe_detail'),
url(r'^$', RecipeListView.as_view(), name='recipes_recipe_index'),
)
© Juergen Schackmann 2012 52/69
Typische Project Url Konfiguration
▸ Vial Include werden Url Konfigurationen ineinander geschachtelt
▸ Vorallem App Urls ==> Project Urls
▸ Achtung: Url von Apps nicht fix, sondern abhängig von Project ==> reverse lookup
admin.autodiscover() # ueblich wenn admin verwendet wird
urlpatterns = patterns('',
url(r'^$', 'recipes.views.home', name='home'),
url(r'^recipes/', include('recipes.urls')),
url(r'^admin/', include(admin.site.urls)),
)
© Juergen Schackmann 2012 53/69
Reverse URL Lookup
# in templates mit template tag
{% url recipes_recipe_add %}
# im python code
reverse('recipes_recipe_detail', kwargs={'pk':id})
# via get_absolute_url und permalink decorator
recipe.get_absolute_url()
© Juergen Schackmann 2012 54/69
Django Http Request Lifecycle
Django HTTP
HandlerView
Model
Templates
View Middleware
Url ConfigRequest
Middleware
Exception Middleware
Response Middleware
Admin
© Juergen Schackmann 2012 56/69
Django.contrib.admin
▸ Meistgenutzte Applikation
▸ Größter Django Selling Point
▸ Hierarchische Struktur
▸ Liste aller Apps
▸ Liste aller Models je App
▸ List und Detail View je Model
▸ Dynamische Generierung der Seiten auf Basis der Models
▸ Sehr umfangreiches Customizing möglich
▸ Unterschiedliche Admin Sites mit unterschiedlichen Ausprägungen möglich
© Juergen Schackmann 2012 57/69
Admin Beispiel
class RecipeAdmin(admin.ModelAdmin):
fields = ['title','preparation', 'date_created']
def get_query_set(self,request):
return Recipe.objects.filter(active=True)
admin.site.register(Category)
admin.site.register(Recipe, RecipeAdmin)
© Juergen Schackmann 2012 58/69
Screenshots
▸ xxx
Settings
© Juergen Schackmann 2012 60/69
Settings.py
▸ Zentrale Konfiguration Django Project
▸ Python File
▸ 100+ Django Settings (mit sinnvollen defaults)
▸ Datenbank
▸ Apps
▸ Template Verzeichnisse
▸ Statische Verzeichnisse
▸ Middleware
▸ Locale, Timezone, …
▸ Kann auch for eigene App settings genutzt werden
▸ Docs: docs.djangoproject.com/en/1.4/ref/settings/
© Juergen Schackmann 2012 61/69
Wichtige Settings Einstellungen
▸ DEBUG
▸ Datenbank
▸ Installed Apps
▸ Middleware
▸ Context_Processors
▸ Statische Verzeichnisse
▸ Template Verzeichnisse
▸ Timezone
▸ Locale
© Juergen Schackmann 2012 62/69
Typische Django App Liste (settings.py)
INSTALLED_APPS = ( 'django.contrib.auth', << User Management, Authentifizierung, Autorisierung 'django.contrib.contenttypes', << Dependency für folgende 'django.contrib.sessions', << Session Management 'django.contrib.sites', << Betreiben mehrere Sites aus einem Projekt 'django.contrib.messages', << Messages im Browser 'django.contrib.staticfiles', << Statische files für Entwicklung und Deployment 'django.contrib.admin', << Admin für alle apps (sehr nützlich) 'south', << Datenschema Migration 'debug_toolbar' << Debug Toolbar im Browser (für Entwicklung) 'nuts1', << Custom App 'nuts2', << Custom App)
© Juergen Schackmann 2012 63/69
Typische Settings Komponenten
▸ Bestimmung Project Root für generische Verweise auf Verzeichnisse
PROJECT_ROOT = dir(abspath(__file__)) # Kann ff für Verzeichnisdefinition verwendet werden
TEMPLATE_DIRS=(join(PROJECT_ROOT,'templates'))
if DEBUG:
….
▸ Definition von settings in Abhängigkeit von Debug setting
© Juergen Schackmann 2012 64/69
Settings in komplexen Umgebungen
▸ Verteilung settings auf verschiedenen files
▸ Unterschiedliche Settings Files für unterschiedliche Umgebungen
▸ Import files in “master” settings file in Abhängigkeit von bestimmten Bedingungen
import common_settings
if environ('DJANGO_ENVIRONMENT')=='DEV':
import dev_settings
else:
import prod_settings
try:
import local_settings
except:
pass
© Juergen Schackmann 2012 65/69
Zugriff auf Settings und App Settings
▸ Zugriff auf settings via django.conf.settings object
▸ Django Default Settings
▸ Project Settings
▸ Lazy Loading
▸ In settings.py sind nicht nur Django Core Settings erlaubt
▸ Jede App kann eigene settings definieren und nutzen
from django.conf import settings
NUTS_MY_SETTING =settings.get('NUTS_MY_SETTING','My_Default')
Room for Improvement?
© Juergen Schackmann 2012 67/69
Pro Django
▸ Sehr flache Lernkurve
▸ Genügend Flexibilität bei komplexen Anforderungen
▸ Modulares Gesamtkonzept
▸ Sehr großes App Ökosystem
▸ Große Community und nachhaltige Entwicklung
© Juergen Schackmann 2012 68/69
“Batteries Included”
▸ Admin
▸ Session Handling
▸ User Management, Authentifizeirung, Authorisierung, Permissions
▸ Comments
▸ Tags
▸ Static Files
▸ Content Types
▸ Internationalisierung, Lokalisierung
▸ Caching
© Juergen Schackmann 2012 69/69
Room for Improvement
▸ Convention sehr liberal
▸ Pluggable != Pluggable
▸ Viele Apps für das selbe Problem
▸ Qualität der Apps sehr unterschiedlich
▸ Fehlende Contrib Apps:
▸ Workflow
▸ Object Permissions
▸ Schema Migration
▸ Python 3 support für apps