wake-up-neo.com

Favorit Django Tipps & Eigenschaften?

Inspiriert von der Fragenserie 'Hidden features of ...', bin ich gespannt auf Ihre bevorzugten Django Tipps oder weniger bekannte, aber nützliche Funktionen, die Sie kennen.

  • Bitte geben Sie nur einen Tipp pro Antwort an.
  • Fügen Sie ggf. Django Versionsanforderungen hinzu.
308
Haes

Ich werde nur mit einem Tipp von mir selbst beginnen :)

Verwenden Sie os.path.dirname () in settings.py, um fest codierte Verzeichnisnamen zu vermeiden.

Verwenden Sie in Ihren settings.py keinen Hardcode-Pfad, wenn Sie Ihr Projekt an verschiedenen Orten ausführen möchten. Verwenden Sie den folgenden Code in settings.py, wenn sich Ihre Vorlagen und statischen Dateien im Projektverzeichnis Django befinden:

# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, "templates"),
)

Credits: Ich habe diesen Tipp aus dem Screencast ' Django From the Ground Up ' erhalten.

222
Haes

Installieren Sie Django Command Extensions und pygraphviz und geben Sie dann den folgenden Befehl ein, um eine wirklich gut aussehende Django Modellvisualisierung zu erhalten:

./manage.py graph_models -a -g -o my_project.png
130
Haes

Verwende Django-ärgerlichrender_to Dekorateur statt render_to_response.

@render_to('template.html')
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return {'bars': bars}

# equals to
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return render_to_response('template.html',
                              {'bars': bars},
                              context_instance=RequestContext(request))

Bearbeitet, um darauf hinzuweisen, dass das Zurückgeben einer HttpResponse (z. B. einer Umleitung) den Decorator kurzschließt und wie erwartet funktioniert.

119
user20955

Es gibt eine Reihe von benutzerdefinierten Tags, die ich in allen Vorlagen meiner Website verwende. Auf der Suche nach einer Möglichkeit, es automatisch zu laden (DRY, erinnerst du dich?), Fand ich Folgendes:

from Django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')

Wenn Sie dies in ein Modul einfügen, das standardmäßig geladen ist (z. B. Ihre Haupt-URL-Adresse), stehen die Tags und Filter Ihres benutzerdefinierten Tag-Moduls in jeder Vorlage zur Verfügung, ohne {% load custom_tag_module %} Zu verwenden.

Das an template.add_to_builtins() übergebene Argument kann ein beliebiger Modulpfad sein. Ihr benutzerdefiniertes Tag-Modul muss sich nicht in einer bestimmten Anwendung befinden. Beispielsweise kann es sich auch um ein Modul im Stammverzeichnis Ihres Projekts handeln (z. B. 'project.custom_tag_module').

102
Steef

Virtualenv + Python = Lebensretter, wenn Sie an mehreren Django Projekten arbeiten und es die Möglichkeit gibt, dass dies nicht alle tun abhängig von der gleichen Version von Django/einer Anwendung.

97
phillc

Kodieren Sie Ihre URLs nicht hart!

Verwenden Sie stattdessen RL-Namen und die Funktion reverse , um die URL selbst abzurufen.

Wenn Sie Ihre URL-Zuordnungen definieren, geben Sie Ihren URLs Namen.

urlpatterns += ('project.application.views'
   url( r'^something/$', 'view_function', name="url-name" ),
   ....
)

Stellen Sie sicher, dass der Name pro URL eindeutig ist.

Ich habe normalerweise ein konsistentes Format "Projektanwendungsansicht", z. "cbx-forum-thread" für eine Threadansicht.

[~ # ~] Update [~ # ~] (schamlos stehlen Ayaz's Zugabe ):

Dieser Name kann in Vorlagen mit dem Tag url verwendet werden.

88
hasen

Verwenden Sie Django Debug Toolbar . Beispielsweise können Sie alle SQL-Abfragen anzeigen, die während der Rendering-Ansicht ausgeführt wurden, und Sie können die Stapelverfolgung für jede dieser Abfragen anzeigen.

82
Eugene Morozov

Schreiben Sie keine eigenen Anmeldeseiten. Wenn Sie Django.contrib.auth verwenden.

Das wirkliche, schmutzige Geheimnis ist, dass, wenn Sie auch Django.contrib.admin verwenden und Django.template.loaders.app_directories.load_template_source in Ihren Vorlagenladern ist, Sie können Ihre Vorlagen auch kostenlos erhalten!

# somewhere in urls.py
urlpatterns += patterns('Django.contrib.auth',
    (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
    (r'^accounts/logout/$','views.logout'),
)

Kontextprozessoren sind fantastisch.

Angenommen, Sie haben ein anderes Benutzermodell und möchten dies in jede Antwort einbeziehen. Anstatt dies zu tun:

def myview(request, arg, arg2=None, template='my/template.html'):
    ''' My view... '''
    response = dict()
    myuser = MyUser.objects.get(user=request.user)
    response['my_user'] = myuser
    ...
    return render_to_response(template,
                              response,
                              context_instance=RequestContext(request))

Mit Kontextprozessen können Sie beliebige Variablen an Ihre Vorlagen übergeben. Normalerweise gebe ich meine in 'my_project/apps/core/context.py Ein:

def my_context(request):
    try:
        return dict(my_user=MyUser.objects.get(user=request.user))
    except ObjectNotFound:
        return dict(my_user='')

Fügen Sie in Ihrem settings.py Die folgende Zeile zu Ihrem TEMPLATE_CONTEXT_PROCESSORS Hinzu

TEMPLATE_CONTEXT_PROCESSORS = (
    'my_project.apps.core.context.my_context',
    ...
)

Bei jeder Anforderung wird nun automatisch der Schlüssel my_user Eingefügt.

Auch Signale gewinnen.

Ich habe vor ein paar Monaten einen Blog-Beitrag darüber geschrieben, also werde ich einfach ausschneiden und einfügen:

Out of the Box Django gibt Ihnen mehrere Signale, die unglaublich nützlich sind. Sie haben die Möglichkeit, Dinge vor und nach dem Speichern, Initialisieren, Löschen oder sogar während der Verarbeitung einer Anfrage zu tun Gehen Sie von den Konzepten weg und zeigen Sie, wie diese verwendet werden. Sagen Sie, wir haben einen Blog

from Django.utils.translation import ugettext_lazy as _
class Post(models.Model):
    title = models.CharField(_('title'), max_length=255)
    body = models.TextField(_('body'))
    created = models.DateTimeField(auto_now_add=True)

Sie möchten also auf irgendeine Weise einen der vielen Blog-Ping-Dienste benachrichtigen, die wir für einen neuen Beitrag eingerichtet haben, den Cache der neuesten Beiträge neu erstellen und darüber twittern. Mit Signalen haben Sie die Möglichkeit, all dies zu tun, ohne der Post-Klasse Methoden hinzufügen zu müssen.

import Twitter

from Django.core.cache import cache
from Django.db.models.signals import post_save
from Django.conf import settings

def posted_blog(sender, created=None, instance=None, **kwargs):
    ''' Listens for a blog post to save and alerts some services. '''
    if (created and instance is not None):
        Tweet = 'New blog post! %s' instance.title
        t = Twitter.PostUpdate(settings.Twitter_USER,
                               settings.Twitter_PASSWD,
                               Tweet)
        cache.set(instance.cache_key, instance, 60*5)
       # send pingbacks
       # ...
       # whatever else
    else:
        cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)

Dort definieren wir diese Funktion und verwenden das Signal post_init, um die Funktion mit dem Post-Modell zu verbinden und es auszuführen, nachdem es gespeichert wurde.

67
notzach

Als ich anfing, wusste ich nicht, dass es einen Paginator gibt, stellen Sie sicher, dass Sie von seiner Existenz wissen !!

57
hasen

Verwenden Sie IPython , um auf jeder Ebene in Ihren Code zu springen und mit der Leistungsfähigkeit von IPython zu debuggen. Sobald Sie IPython installiert haben, geben Sie diesen Code einfach an der Stelle ein, an der Sie debuggen möchten:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()

Aktualisieren Sie dann die Seite, gehen Sie zu Ihrem Runserver-Fenster und Sie befinden sich in einem interaktiven IPython-Fenster.

Ich habe ein Snippet in TextMate eingerichtet, tippe also einfach ipshell und drücke die Tabulatortaste. Ich könnte nicht ohne es leben.

47
sheats

Führen Sie einen Entwicklungs-SMTP-Server aus, der nur das ausgibt, was an ihn gesendet wird (wenn Sie SMTP nicht tatsächlich auf Ihrem Entwicklungsserver installieren möchten).

befehlszeile:

python -m smtpd -n -c DebuggingServer localhost:1025
43
Carl G

Aus der Django-Admin-Dokumentation :

Wenn Sie die Bash-Shell verwenden, sollten Sie erwägen, das Bash-Abschlussskript Django zu installieren, das in extras/Django_bash_completion in der Distribution Django enthalten ist. Es ermöglicht die Tab-Vervollständigung von Django-admin.py und manage.py Befehlen, so dass Sie zum Beispiel ...

  • Geben Sie Django-admin.py ein.
  • Drücken Sie [TAB], um alle verfügbaren Optionen anzuzeigen.
  • Geben Sie sql und dann [TAB] ein, um alle verfügbaren Optionen anzuzeigen, deren Namen mit sql beginnen.
41
John

Die Funktion ./manage.py runserver_plus, Die mit Django_extensions geliefert wird, ist wirklich fantastisch.

Es wird eine erweiterte Debug-Seite erstellt, die unter anderem den Werkzeug-Debugger verwendet, um interaktive Debug-Konsolen für jeden Punkt im Stapel zu erstellen (siehe Screenshot). Es bietet auch eine sehr nützliche Debugging-Methode dump() zum Anzeigen von Informationen zu einem Objekt/Frame.

enter image description here

Zum Installieren können Sie pip verwenden:

pip install Django_extensions
pip install Werkzeug

Fügen Sie dann 'Django_extensions' Zu Ihrem INSTALLED_APPS - Tupel in settings.py Hinzu und starten Sie den Entwicklungsserver mit der neuen Erweiterung:

./manage.py runserver_plus

Dies ändert die Art und Weise, wie Sie debuggen.

40

Beim Versuch, Daten zwischen Django und einer anderen Anwendung auszutauschen, wird request.raw_post_data ist ein guter Freund. Verwenden Sie es, um beispielsweise XML-Daten zu empfangen und individuell zu verarbeiten.

Dokumentation: http://docs.djangoproject.com/en/dev/ref/request-response/

37
chefsmart

Ich benutze gerne den Python debugger pdb um Django projekte zu debuggen.

Dies ist ein hilfreicher Link zum Erlernen der Verwendung: http://www.ferg.org/papers/debugging_in_python.html

37
Harold

Hinzufügen assert False in Ihrem Ansichtscode, um Debug-Informationen zu sichern.

35
zgoda

Benutze Jinja2 neben Django.

Wenn Sie die Django Template-Sprache extrem einschränkend finden (wie ich!), Müssen Sie nicht daran festhalten. Django ist flexibel, und die Die Vorlagensprache ist lose mit dem Rest des Systems verbunden. Fügen Sie einfach eine andere Vorlagensprache hinzu und verwenden Sie sie, um Ihre http-Antworten zu rendern.

Ich benutze Jinja2 , es ist fast wie eine eingeschaltete Version der Django Template-Sprache, es verwendet die gleiche Syntax und erlaubt es Ihnen, Ausdrücke in if-Anweisungen zu verwenden! Wenn Sie keine benutzerdefinierten if-Tags wie if_item_in_list erstellen, können Sie einfach %{ if item in list %} oder {% if object.field < 10 %} sagen.

Aber das ist nicht alles; Es hat viele weitere Funktionen, um die Erstellung von Vorlagen zu vereinfachen, die ich hier nicht alle durchgehen kann.

35
hasen

Dies ergänzt die Antwort oben um Django-URL-Namen und umgekehrte URL-Verteilung .

Die URL-Namen können auch effektiv in Vorlagen verwendet werden. Zum Beispiel für ein bestimmtes URL-Muster:

url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')

sie können Folgendes in Vorlagen haben:

<a href="{% url project_team project.id %}">Team</a>
33
ayaz

Da Django "Ansichten" nur Callables sein müssen, die eine HttpResponse zurückgeben, können Sie einfach klassenbasierte Ansichten wie die in Ruby auf Rails und anderen Frameworks erstellen.

Es gibt verschiedene Möglichkeiten, klassenbasierte Ansichten zu erstellen:

from Django import http

class RestView(object):
    methods = ('GET', 'HEAD')

    @classmethod
    def dispatch(cls, request, *args, **kwargs):
        resource = cls()
        if request.method.lower() not in (method.lower() for method in resource.methods):
            return http.HttpResponseNotAllowed(resource.methods)
        try:
            method = getattr(resource, request.method.lower())
        except AttributeError:
            raise Exception("View method `%s` does not exist." % request.method.lower())
        if not callable(method):
            raise Exception("View method `%s` is not callable." % request.method.lower())
        return method(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return http.HttpResponse()

    def head(self, request, *args, **kwargs):
        response = self.get(request, *args, **kwargs)
        response.content = ''
        return response

Sie können in Ihrer Basisansicht alle möglichen anderen Dinge wie die Bearbeitung bedingter Anfragen und die Autorisierung hinzufügen.

Sobald Sie Ihre Ansichten eingerichtet haben, sieht Ihre urls.py so aus:

from Django.conf.urls.defaults import *
from views import MyRestView

urlpatterns = patterns('',
    (r'^restview/', MyRestView.dispatch),
)
27
mmalone

Anstelle von render_to_response Um Ihren Kontext an eine Vorlage zu binden und diese zu rendern (was in den Django docs normalerweise angezeigt wird)), verwenden Sie die generische Ansicht direct_to_template . Es macht das gleiche, dass render_to_response fügt jedoch automatisch RequestContext zum Vorlagenkontext hinzu, sodass implizit Kontextprozessoren verwendet werden können. Sie können dies manuell mit render_to_response, aber warum die Mühe machen? Es ist nur ein weiterer zu merkender Schritt und ein weiterer LOC. Neben der Verwendung von Kontextprozessoren können Sie mit RequestContext in Ihrer Vorlage Folgendes tun:

<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a> 

das ist sehr nützlich. Tatsächlich +1 für allgemeine Ansichten im Allgemeinen. In den Django docs werden sie meist als Verknüpfungen angezeigt, wenn für einfache Apps nicht einmal eine views.py-Datei vorhanden ist. Sie können sie jedoch auch in Ihren eigenen Ansichtsfunktionen verwenden:

from Django.views.generic import simple

def article_detail(request, slug=None):
    article = get_object_or_404(Article, slug=slug)
    return simple.direct_to_template(request, 
        template="articles/article_detail.html",
        extra_context={'article': article}
    )
21
mazelife

Ich habe nicht genug Reputation, um auf den fraglichen Kommentar zu antworten, aber es ist wichtig zu beachten, dass wenn Sie Jinja verwenden, das '-' Zeichen in Template-Blocknamen NICHT unterstützt wird , während Django tut. Dies verursachte mir eine Menge Probleme und verschwendete Zeit beim Versuch, die sehr dunkle Fehlermeldung aufzuspüren, die sie erzeugte.

20
user61000

Die Webdesign-App ist sehr nützlich, wenn Sie mit der Gestaltung Ihrer Website beginnen. Nach dem Import können Sie Folgendes hinzufügen, um Beispieltext zu generieren:

{% load webdesign %}
{% lorem 5 p %}
19
Ross Light

Django.db.models.get_model ermöglicht es Ihnen, ein Modell abzurufen, ohne es zu importieren.

James zeigt, wie praktisch es sein kann: "Django-Tipps: Bessere Vorlagen-Tags schreiben - Iteration 4" .

19
vikingosegundo

Jeder weiß, dass es einen Entwicklungsserver gibt, den Sie mit "manage.py runserver" ausführen können, aber wussten Sie, dass es auch eine Entwicklungsansicht für die Bereitstellung statischer Dateien (CSS/JS/IMG) gibt?

Neulinge sind immer verwirrt, weil Django keine Möglichkeit bietet, statische Dateien bereitzustellen. Dies liegt daran, dass das Entwicklerteam denkt, es sei die Aufgabe eines echten Webservers.

Aber wenn Sie entwickeln, möchten Sie vielleicht nicht Apache + mod_wisgi einrichten, es ist schwer. Dann können Sie der urls.py einfach Folgendes hinzufügen:

(r'^site_media/(?P<path>.*)$', 'Django.views.static.serve',
        {'document_root': '/path/to/media'}),

Ihr CSS/JS/IMG finden Sie unter www.yoursite.com/site_media/.

Verwenden Sie es natürlich nicht in einer Produktionsumgebung.

19
e-satis

Ich habe dies aus der Dokumentation für die sorl-thumbnails App gelernt. Sie können das Schlüsselwort "as" in Vorlagen-Tags verwenden, um die Ergebnisse des Aufrufs an einer anderen Stelle in Ihrer Vorlage zu verwenden.

Beispielsweise:

{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>

Dies wird im Django templatetag documentation, aber nur in Bezug auf Schleifen erwähnt. Sie rufen nicht hervor, dass Sie dies auch an anderer Stelle (irgendwo?) Verwenden können.

18
Joe Kueser

PyCharm IDE ist eine nette Umgebung zum Programmieren und insbesondere zum Debuggen, mit eingebauter Unterstützung für Django.

16
Art

Django.views.generic.list_detail.object_list - Es enthält alle Logik- und Vorlagenvariablen für die Paginierung (eine der Aufgaben, die ich bisher tausend Mal geschrieben habe). Wrapping it erlaubt jede Logik, die Sie brauchen. Durch dieses Juwel habe ich viele Stunden Zeit gespart, um einzelne Fehler auf meinen Seiten mit den Suchergebnissen zu beheben, und den Anzeigecode dabei übersichtlicher gestaltet.

16
jds

Verwenden Sie Datenbankmigrationen. Verwenden Sie Süd .

14
vad

Verwenden Sie xml_models , um Django= Modelle zu erstellen, die ein XML REST API-Backend (anstelle eines SQL-Backends) verwenden. Dies ist sehr nützlich Insbesondere beim Modellieren von Drittanbieter-APIs erhalten Sie dieselbe QuerySet-Syntax, die Sie gewohnt sind. Sie können sie über PyPI installieren.

XML aus einer API:

<profile id=4>
    <email>[email protected]</email>
    <first_name>Joe</first_name>
    <last_name>Example</last_name>
    <date_of_birth>1975-05-15</date_of_birth>
</profile>

Und jetzt in Python:

class Profile(xml_models.Model):
    user_id = xml_models.IntField(xpath='/profile/@id')
    email = xml_models.CharField(xpath='/profile/email')
    first = xml_models.CharField(xpath='/profile/first_name')
    last = xml_models.CharField(xpath='/profile/last_name')
    birthday = xml_models.DateField(xpath='/profile/date_of_birth')

    finders = {
        (user_id,):  settings.API_URL +'/api/v1/profile/userid/%s',
        (email,):  settings.API_URL +'/api/v1/profile/email/%s',
    }

profile = Profile.objects.get(user_id=4)
print profile.email
# would print '[email protected]'

Es kann auch Beziehungen und Sammlungen verwalten. Wir verwenden es jeden Tag in häufig verwendetem Produktionscode, so dass es, obwohl es sich um Beta handelt, sehr gut verwendbar ist. Es hat auch eine gute Reihe von Stubs, die Sie in Ihren Tests verwenden können.

(Haftungsausschluss: Obwohl ich nicht der Autor dieser Bibliothek bin, bin ich jetzt ein Committer, nachdem ich ein paar kleinere Commits gemacht habe.)

14
godswearhats

Wir haben gerade diesen Link gefunden: http://lincolnloop.com/Django-best-practices/#table-of-contents - "Django Best Practices".

13
None-da

Verwenden Sie .exists () in Django 1.2+ und .count () für frühere Versionen, anstatt den gesamten Abfragesatz auszuwerten, um zu überprüfen, ob Sie Ergebnisse erhalten haben.

Sowohl exists () als auch count () löschen die Reihenfolge nach Klauseln und rufen eine einzelne Ganzzahl aus DB ab. Jedoch gibt exists () immer 1 zurück, wobei count möglicherweise höhere Werte zurückgibt, auf die Limits manuell angewendet werden. Quelle für has_result verwendet in exists () und get_count verwendet in count () für die Neugierigen.

Da beide eine einzelne Ganzzahl zurückgeben, gibt es keine Modellinstanziierung, kein Laden von Modellattributen im Speicher und keine großen TextFields, die zwischen Ihrer Datenbank und der App übertragen werden.

Wenn Sie die Abfrage bereits ausgewertet haben, berechnet .count () len (cached_result) und .exists () bool (cached_result).

Nicht effizient - Beispiel 1

books = Books.objects.filter(author__last_name='Brown')
if books:
    # Do something

Nicht effizient - Beispiel 2

books = Books.objects.filter(author__last_name='Brown')
if len(books):
    # Do something

Effizient - Beispiel 1

books = Books.objects.filter(author__last_name='Brown')
if books.count():
    # Do something

Effizient - Beispiel 2

books = Books.objects.filter(author__last_name='Brown')
if books.exists():
    # Do something
12
tarequeh

Wenn Sie Änderungen am Modell vornehmen

./manage.py dumpdata appname > appname_data.json  
./manage.py reset appname
Django-admin.py loaddata appname_data.json
12

Verwenden Sie signals , um spontan Zugriffsmethoden hinzuzufügen.

Ich habe diese Technik in Django-photologue gesehen: Für jedes hinzugefügte Size-Objekt fügt das post_init-Signal die entsprechenden Methoden zum Image-Modell hinzu. Wenn Sie einen Site-Riesen hinzufügen, lautet die Methode zum Abrufen des Bildes in Riesenauflösung image.get_giant_url().

Die Methoden werden durch Aufrufen von add_accessor_methods Aus dem post_init - Signal generiert:

def add_accessor_methods(self, *args, **kwargs):
    for size in PhotoSizeCache().sizes.keys():
        setattr(self, 'get_%s_size' % size,
                curry(self._get_SIZE_size, size=size))
        setattr(self, 'get_%s_photosize' % size,
                curry(self._get_SIZE_photosize, size=size))
        setattr(self, 'get_%s_url' % size,
                curry(self._get_SIZE_url, size=size))
        setattr(self, 'get_%s_filename' % size,
                curry(self._get_SIZE_filename, size=size))

Siehe den Quellcode von photologue.models zur Verwendung in der realen Welt.

11
vikingosegundo

Entfernen Sie die Datenbankzugriffsinformationen aus settings.py

Eine Sache, die ich in settings.py Meiner Django Site getan habe, ist das Laden von Datenbankzugriffsinformationen aus einer Datei in /etc. Auf diese Weise kann die Zugriffseinstellung (Datenbank-Host, Port, Benutzername, Passwort) für jeden Computer unterschiedlich sein, und vertrauliche Informationen wie das Passwort befinden sich nicht im Repository meines Projekts. Möglicherweise möchten Sie den Zugriff auf die Mitarbeiter auf ähnliche Weise einschränken, indem Sie sie mit einem anderen Benutzernamen verbinden.

Sie können auch die Datenbankverbindungsinformationen oder auch nur einen Schlüssel oder Pfad zu einer Konfigurationsdatei über Umgebungsvariablen übergeben und in settings.py Verarbeiten.

So rufe ich beispielsweise meine Datenbankkonfigurationsdatei auf:

g = {}
dbSetup = {}
execfile(os.environ['DB_CONFIG'], g, dbSetup)
if 'databases' in dbSetup:
    DATABASES = dbSetup['databases']
else:
    DATABASES = {
        'default': {
            'ENGINE': 'Django.db.backends.mysql',
            # ...
        }
    }

Natürlich müssen Sie sicherstellen, dass die Datei in DB_CONFIG Keinem anderen Benutzer als den Datenbankadministratoren und Django selbst zugänglich ist. Der Standardfall sollte Django auf die eigene Testdatenbank eines Entwicklers verweisen. Möglicherweise gibt es auch eine bessere Lösung mit dem Modul ast anstelle von execfile, die ich jedoch noch nicht untersucht habe.

Eine andere Sache, die ich tue, ist, unterschiedliche Benutzer für DB-Verwaltungsaufgaben gegen alles andere zu benutzen. In meinem manage.py Habe ich die folgende Präambel hinzugefügt:

# Find a database configuration, if there is one, and set it in the environment.
adminDBConfFile = '/etc/Django/db_admin.py'
dbConfFile = '/etc/Django/db_regular.py'
import sys
import os
def goodFile(path):
    return os.path.isfile(path) and os.access(path, os.R_OK)
if len(sys.argv) >= 2 and sys.argv[1] in ["syncdb", "dbshell", "migrate"] \
    and goodFile(adminDBConfFile):
    os.environ['DB_CONFIG'] = adminDBConfFile
Elif goodFile(dbConfFile):
    os.environ['DB_CONFIG'] = dbConfFile

Wobei die Konfiguration in /etc/Django/db_regular.py Für einen Benutzer mit Zugriff auf nur die Datenbank Django mit SELECT, INSERT, UPDATE und DELETE ist und /etc/Django/db_admin.py Für einen Benutzer mit diesen Berechtigungen plus CREATE, DROP, INDEX, ALTER und LOCK TABLES. (Der Befehl migrate stammt von South .) Dies bietet mir einen gewissen Schutz vor Django Code, der zur Laufzeit mit meinem Schema in Konflikt gerät, und begrenzt den Schaden einer SQL-Injection Angriffe können dazu führen (obwohl Sie trotzdem alle Benutzereingaben überprüfen und filtern sollten).

(Kopiert von meiner Antwort auf eine andere Frage )

11
Mike DeSimone

Anstatt den Django dev-Server auf localhost auszuführen, führen Sie ihn auf einer geeigneten Netzwerkschnittstelle aus. Beispiel:

python manage.py runserver 192.168.1.110:8000

oder

python manage.py runserver 0.0.0.0:8000

Dann können Sie nicht nur einfach Fiddler ( http://www.fiddler2.com/fiddler2/ ) oder ein anderes Tool wie HTTP Debugger ( http://www.httpdebugger.com/) verwenden. ), um Ihre HTTP-Header zu überprüfen, aber Sie können auch von anderen Rechnern in Ihrem LAN auf Ihre Entwickler-Site zugreifen, um sie zu testen.

Stellen Sie jedoch sicher, dass Sie durch eine Firewall geschützt sind, obwohl der Entwicklungsserver minimal und relativ sicher ist.

9
chefsmart

Die Django Debug Toolbar ist wirklich fantastisch. Es handelt sich nicht wirklich um eine Symbolleiste, sondern um einen Seitenbereich, in dem Sie alle möglichen Informationen darüber finden, wie Sie die Seite aufgerufen haben - DB-Abfragen, die an die Vorlage gesendeten Kontextvariablen, Signale und vieles mehr.

7
Mark Snidovich

Verwenden Sie wraps decorator in benutzerdefinierten Ansichten-Dekoratoren, um den Namen, das Modul und die Dokumentzeichenfolge der Ansicht beizubehalten. Z.B.

try:
    from functools import wraps
except ImportError:
    from Django.utils.functional import wraps  # Python 2.3, 2.4 fallback.

def view_decorator(fun):
    @wraps(fun)
    def wrapper():
        # here goes your decorator's code
    return wrapper

Achtung: Funktioniert nicht in klassenbasierten Ansichten (mit Methodendefinition __call__), Wenn der Autor keine Eigenschaft __name__ Definiert hat. Als Workaround verwenden Sie:

from Django.utils.decorators import available_attrs
...
    @wraps(fun, assigned=available_attrs(fun))
7
trybik

Verwenden eines "Apps" -Ordners zum Organisieren Ihrer Anwendungen, ohne PYTHONPATH zu bearbeiten

Dies ist praktisch, wenn ich meine Ordner folgendermaßen organisieren möchte:

apps/
    foo/
    bar/
site/
settings.py
urls.py

ohne PYTHONPATH zu überschreiben oder zu jedem Import Apps hinzufügen zu müssen wie:

from apps.foo.model import *
from apps.bar.forms import *

In Ihrer settings.py hinzufügen

import os
import sys
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(PROJECT_ROOT, "apps"))

und du bist bereit zu gehen :-)

Ich habe dies bei http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-Django-apps/ gesehen

6
Javi Romero

Formular über Django template anstelle von as_ (ul | table | p) () rendern.

Dieser Artikel zeigt, wie Sie mit Hilfe einer Vorlage CusstomForms anstelle von as_p(), as_table() ... rendern können.

Damit es funktioniert, ändern Sie

  • from Django import newforms as forms bis from Django import forms
  • from Django.newforms.forms import BoundField bis from Django.forms.forms import BoundField
5
vikingosegundo

Automatisches Setzen des 'DEBUG'-Attributs in der Produktionsumgebung (settings.py)

import socket

if socket.gethostname() == 'productionserver.com':
    DEBUG = False
else:
    DEBUG = True

Von: http://nicksergeant.com/2008/automatically-setting-debug-in-your-Django-app-based-on-server-hostname/

5

Verwenden Sie djangorecipe, um Ihr Projekt zu verwalten

  • Wenn Sie eine neue App schreiben, können Sie sie mit diesem Rezept ganz einfach außerhalb eines Projekts testen
  • Hiermit können Sie Abhängigkeiten für ein Projekt verwalten (z. B. von welcher Version einer App es abhängen sollte).

Alles, was Sie tun müssen, um loszulegen, ist Folgendes:

  1. Erstellen Sie einen Ordner für Ihre neue Website (oder Bibliothek)
  2. Erstellen Sie eine buildout.cfg mit folgendem Inhalt:

    
    [buildout]
    parts=Django
    
    [Django]
    recipe=djangorecipe
    version=1.1.1
    project=my_new_site
    settings=development
    
  3. Holen Sie sich eine bootstrap.py, um eine lokale Installation von buildout zu erhalten und in Ihrem Verzeichnis abzulegen. Sie können entweder mit dem offiziellen (Entschuldigung, Markdown mochte keinen Teil des vollständigen Links: - /) gehen oder mit einem, der distribute anstelle von setuptools verwendet, wie von Reinout van) beschrieben Rees .
  4. python bootstrap.py (Oder python bootstrap_dev.py, Wenn Sie distribute verwenden möchten).
  5. ./bin/buildout

Das ist es. Sie sollten jetzt einen neuen Ordner "my_new_site" haben, der Ihr neues Django 1.1.1 Projekt ist, und in ./bin finden Sie das Django-Skript, das das ersetzt manage.py bei einer normalen Installation.

Was ist der vorteil Angenommen, Sie möchten in Ihrem Projekt so etwas wie Django-Kommentar-Spamfighter verwenden. Alles was Sie tun müssen, ist Ihre buildout.cfg in so etwas wie das Folgende zu ändern:


[buildout]
parts=Django

[Django]
recipe=djangorecipe
version=1.1.1
project=my_new_site
settings=development
eggs=
    Django-comments-spamfighter==0.4

Beachten Sie, dass ich nur die letzten beiden Zeilen hinzugefügt habe, in denen steht, dass der Django-Teil auch das Django-comments-spamfighter-Paket in Version 0.4 enthalten sollte. Wenn Sie das nächste Mal ./bin/buildout Ausführen, lädt buildout dieses Paket herunter und ändert ./bin/Django, um es seinem PYTHONPATH hinzuzufügen.

djangorecipe eignet sich auch zum Bereitstellen Ihres Projekts mit mod_wsgi. Füge einfach die Einstellung wsgi=true Zum Django-Teil deiner buildout.cfg hinzu und ein "Django.wsgi" wird in deinem ./bin Ordner erscheinen :-)

Und wenn Sie die Option test auf eine Liste von Anwendungen setzen, erstellt das djangorecipe einen Nice-Wrapper für Sie, der alle Tests für die aufgelistete Anwendung in Ihrem Projekt ausführt.

Wenn Sie eine einzelne App in einer eigenständigen Umgebung zum Debuggen usw. entwickeln möchten, hat Jakob Kaplan-Moss ein ziemlich vollständiges Tutorial zu seinem Blog

5
Horst Gutmann

Verwenden Sie reverse in Ihrer URL.

Dies ist einer dieser Tricks, bei denen ich nicht verstehe, warum dies nicht der Standard ist.

Hier ist ein Link, wo ich es aufgenommen habe: http://andr.in/2009/11/21/calling-reverse-in-Django/

Hier ist das Code-Snippet:

from Django.conf.urls.defaults import *
from Django.core.urlresolvers import reverse
from Django.utils.functional import lazy
from Django.http import HttpResponse

reverse_lazy = lazy(reverse, str)

urlpatterns = patterns('',
url(r'^comehere/', lambda request: HttpResponse('Welcome!'), name='comehere'),
url(r'^$', 'Django.views.generic.simple.redirect_to',
{'url': reverse_lazy('comehere')}, name='root')
)
5
jfenwick

Auf diese einfache Weise müssen Sie nie wieder ein anderes Modell in Ihre python Shell importieren.

Installieren Sie zuerst IPython (Wenn Sie IPython nicht verwenden, was ist mit Ihnen los?). Erstellen Sie als Nächstes ein python Skript, ipythonrc.py, in Ihrem Django Projektverzeichnis mit dem folgenden Code:

from Django.db.models.loading import get_models 
for m in get_models(): 
     globals()[m.__name__] = m 
#NOTE: if you have two models with the same name you'll only end up with one of them

Fügen Sie dann in Ihrer ~/.ipython/ipythonrc-Datei den folgenden Code in den Abschnitt "Zu ladende und auszuführende Python-Dateien" ein:

execfile /path/to/project/ipythonrc.py

Jetzt haben Sie jedes Mal, wenn Sie IPython starten oder ./manage.py Shell Ausführen, alle Ihre Modelle bereits importiert und einsatzbereit. Sie müssen nie wieder ein anderes Modell importieren.

Sie können auch jeden anderen Code, den Sie häufig ausführen, in Ihre ipythonrc.py-Datei einfügen, um Zeit zu sparen.

4
sheats

Ändern von Django Formularfeldeigenschaften bei Init

Manchmal ist es nützlich, zusätzliche Argumente an eine Form-Klasse zu übergeben.

from Django import forms
from mymodels import Group

class MyForm(forms.Form):
    group=forms.ModelChoiceField(queryset=None)
    email=forms.EmailField()
    some_choices=forms.ChoiceField()


    def __init__(self,my_var,*args,**kwrds):
        super(MyForm,self).__init__(*args,**kwrds)
        self.fields['group'].queryset=Group.objects.filter(...)
        self.fields['email'].widget.attrs['size']='50'
        self.fields['some_choices']=[[x,x] for x in list_of_stuff]

quelle: Dzone-Schnipsel

4
jbochi

PyCharm und Wingware IDE ist ein großartiges Tool, wenn Sie Geld für die Lizenz haben.

Da ich ein schlechter Entwickler bin, verwende ich PyDev mit Eclipse .

2
kelvinfix

Django_extensions from https://github.com/Django-extensions/Django-extensions ist einfach toll.

Einige nette ./manage.py Befehle:

  • Shell_plus - Importiert Modelle aus allen INSTALLED_APPS automatisch
  • show_urls - druckt alle in allen Apps im Projekt definierten URLs
  • runscript - führt jedes Skript im Projektkontext aus (Sie können Modelle und andere Django-bezogene Module verwenden)
2
gorsky

Verwenden Sie asynchrone Tasks. Verwenden Sie Sellerie

1
vad

Lies nbreaking Django , falls du es noch nicht getan hast. Es enthält viele nützliche Informationen zu Django Fallstricken.

1
tback

Erstellen Sie dynamische Modelle für Gruppen von Legacy-Tabellen mit derselben Struktur:

class BaseStructure(models.Model):
    name = models.CharField(max_length=100)
    address = models.CharField(max_length=100)

    class Meta:
        abstract=True

class DynamicTable(models.Model):
    table_name = models.CharField(max_length=20)

    def get_model(self):
        class Meta:
            managed=False
            table_name=self.table_name

        attrs = {}
        attrs['Meta'] = Meta

        # type(new_class_name, (base,classes), {extra: attributes})
        dynamic_class = type(self.table_name, (BaseStructure,), attrs) 
        return dynamic_class

customers = DynamicTable.objects.get(table_name='Customers').get_model()
me = customers.objects.get(name='Josh Smeaton')
me.address = 'Over the Rainbow'
me.save()

Dies setzt voraus, dass Sie über Legacy-Tabellen mit derselben Struktur verfügen. Anstatt ein Modell zum Umschließen jeder Tabelle zu erstellen, definieren Sie ein Basismodell und erstellen dynamisch die Klasse, die für die Interaktion mit einer bestimmten Tabelle erforderlich ist.

1
Josh Smeaton

Verwenden Sie isapi-wsgi und Django-pyodbc , um Django unter Windows mit IIS und SQL Server) auszuführen !

1
Jason Baker

Ein bisschen zu spät zur Party. Aber Django Canvas ist kürzlich herausgekommen und verdient hier einen Platz.

Beginnen Sie Ihr Projekt nicht mit Django-admin.py startproject. Stattdessen können Sie etwas wie Django Canvas verwenden, um ein leeres Projekt mit den benötigten Modulen zusammenzusetzen.

Sie gehen zu dieser Site, kreuzen einige Optionen an und laden dann ein leeres Projekt herunter, so einfach.

Es enthält alle gängigen Dinge wie South-Schema-Migrationen und Befehlserweiterungen sowie viele andere hier erwähnte Best Practices. Plus es hat ein tolles start.sh/shart.bat Skript, das Python, Virtualenv, Pip, Django und alles, was Sie brauchen, um von einer neuen Kopie von Windows, OSX oder Linux zu starten, installiert.

1
Keyo

Da Django keine App-Einstellungen hat, habe ich meine eigene app_settings.py-Erkennung durchgeführt. Am Ende der settings.py habe ich diesen Code hinzugefügt:

import sys, os
# Append application settings without triggering the __init__.
for installed_app in INSTALLED_APPS:
    # Ignore Django applications
    if not installed_app.startswith('Django.'):
        # Find the app (and the settings file)
        for path in sys.path:
            path = os.path.join(path, installed_app, 'app_settings.py')
            if os.path.isfile(path):
                # Application settings found
                exec open(path).read()

Es erkennt app_settings.py in allen INSTALLED_APPS. Anstatt es zu importieren, liest es den Inhalt der Datei app_settings und führt es inline aus. Wenn app_settings direkt importiert wird, werden alle Arten von Django Importfehlern ausgelöst (weil Django ist noch nicht initialisiert).

Meine app/app_settings.py sieht also so aus:

MIDDLEWARE_CLASSES += (
    'app.middleware.FancyMiddleware',
)

Jetzt muss die Anwendung nur noch zu INSTALLED_APPS hinzugefügt werden, anstatt alle Anwendungseinstellungen zu finden und zur settings.py hinzuzufügen (Middleware, URLs ...)

Hinweis: Es wäre besser, wenn Django hatte einen Haken, um zusätzliche Einstellungen anzufügen, so dass Anwendungseinstellungen beim Start (oder in der Laufzeit) hinzugefügt werden könnten.

0
Willian

Wenn Sie Variablen von einer Ansicht an eine Vorlage übergeben, kann das Eingeben des Antwortwörterbuchs mühsam werden. Ich finde es schön, alle lokalen Variablen auf einmal mit locals() zu übergeben.

def show_thing(request, thing_id):
    thing = Thing.objects.get(pk=thing_id)
    return render_to_response('templates/things/show.html', locals())

(Kein verstecktes Feature an sich, aber trotzdem hilfreich, wenn es neu in Python und oder Django ist.)

Bearbeiten: Natürlich ist es besser, explizit als implizit zu sein, aber dieser Ansatz kann bei der Entwicklung hilfreich sein.

0
droidballoon

dir () & erhöhe ValueError ()

Um den Stand der Dinge während der Entwicklung zu debuggen/untersuchen, benutze ich den folgenden Trick:

...
  to_see = dir(inspect_this_thing)
  to_see2 = inspect_this_thing.some_attribute
  raise ValueError("Debugging")
...

Dies ist besonders hilfreich, wenn Sie an Teilen von Django) arbeiten, die nicht besonders gut dokumentiert sind (form.changed_fields habe ich kürzlich verwendet).

Einheimische ().

Anstatt jede Variable für den Vorlagenkontext auszuschreiben, verwenden Sie den Befehl python builtin locals (), der ein Wörterbuch für Sie erstellt:

#This is tedious and not very DRY
return render_to_response('template.html', {"var1": var1, "var2":var2}, context_instance=RequestContext(request))

#95% of the time this works perfectly
return render_to_response('template.html', locals(), context_instance=RequestContext(request))

#The other 4.99%
render_dict = locals()
render_dict['also_needs'] = "this value"
return render_to_response('template.html', render_dict, context_instance=RequestContext(request))
0
Ted