2013-02-11 13 views
8

Vor klassenbasierten Ansichten gab es ein Schlüsselwort extra_context, das in urlsconf übergeben werden kann. https://docs.djangoproject.com/en/1.3/topics/generic-views/#adding-extra-contextklassenbasierte generische Ansichten zusätzlicher Kontext

Jetzt mit Klasse auf Basis generischen Ansichten, wenn wir das gleiche tun wollen, müssen wir die allgemeine Ansicht https://docs.djangoproject.com/en/1.3/topics/class-based-views/#adding-extra-context

Unterklasse Wenn wir etwas einfach wollen, und wir die generische und Create UpdateView verwenden. Diese Herangehensweise wird dazu zwingen, für etwas, das vorher trivial war, Unterklassen zu bilden. Mehr noch, wir müssen das DRY-Prinzip brechen, und zwar zweimal.

Warum ist es so? Gibt es einen Grund, warum wir den zusätzlichen Kontext nicht direkt an die Vorlage übergeben können?

Dank

Antwort

13

Nach zu vielen Gedanken, ist die einzige Antwort NEIN, dass die Funktionalität entfernt wurde.

Und die Dokumentation erwähnt nicht die "Removed-Funktion" und es gibt keine Erklärung, warum es so war.

Aber mein Leben leichter zu machen habe ich den Rat von @aidan und modifiziert, um ein wenig

class ExtraContext(object): 
    extra_context = {} 

    def get_context_data(self, **kwargs): 
     context = super(ExtraContext, self).get_context_data(**kwargs) 
     context.update(self.extra_context) 
     return context 

class ExtraListView(ExtraContext, ListView): 
    pass 

class ExtraDetailView(ExtraContext, DetailView): 
    pass 

class ExtraUpdateView(ExtraContext, UpdateView): 
    pass 

class ExtraCreateView(ExtraContext, CreateView): 
    pass 

class ExtraDeleteView(ExtraContext, DeleteView): 
    pass 

class ExtraCloneView(ExtraUpdateView): 
    def post(self, request, *args, **kwargs): 
     return ExtraCreateView.as_view(model=self.model, 
           template_name=self.template_name, 
           extra_context=self.extra_context)(request, *args, **kwargs)  

Jetzt habe ich semi-generische Ansichten, die ich direkt im URLSconf und extra_context dict zum Pass verwenden können as_view() aufrufen

url(r'^camera/(?P<pk>\d+)/$', 
    views.ExtraDetailView.as_view(model=models.Camera, 
           extra_context={'action_type': 'detail', 'mod_name' : 'camera'}, 
           template_name='cameras/camera_detail.html'), 
    name='camera_detail'), 
+0

Froh, dass ich helfen konnte. –

+0

Vielen Dank für diese Lösung, ich machte fast alle mein Projekt um klassenbasierte generische Ansichten auf URLs, und ohne diese hätte ich alles ändern müssen – guinunez

8

Ich denke, es ist nicht ganz so einfach ist, aber es ist immer noch nur 5 Zeilen Code -

class MyView(CreateView): 
    def get_context_data(self, *args, **kwargs): 
     context = super(MyView, self).get_context_data(*args, **kwargs) 
     context['my_additional_context'] = my_object 
     return context 

Wenn Sie wirklich, dass die Funktionalität mit Klasse basierte Ansichten möchten, dann vielleicht könnten Sie die erweitern Klasse, um es hinzuzufügen -

class MyCreateView(CreateView) 
    additional_context = {} 
    def get_context_data(self, *args, **kwargs): 
     context = super(MyView, self).get_context_data(*args, **kwargs) 
     context.append(self.additional_context) 
     return context 

es dann in Ihrem url_conf verwenden -

urlpatterns = patterns('', 
    #.... 
    (r'^my_url/$', MyCreateView.as_view(additional_context={'my_addional_context': my_object})), 
) 

Sie könnten Ihre eigenen CreateView, DetailView, ListView usw. schreiben und importieren Sie sie in jedes Projekt, das Sie tun.

+0

Das Problem ist nicht, wie es die generische Ansichten Unterklasse, die Probleme ist, dass diese Funktionalität entfernt wurde. – fariza

+0

ja, denke ich. Ich habe wirklich keine Antwort auf deine Frage. Ich weiß nicht, warum es entfernt wurde. –

+0

dies funktioniert, aber es gibt eine alte Django-Regel "Übergeben Sie nichts an URL-Ansichten in der URL-Datei!" das wird es langsamer machen!Ressource von zwei Schaufeln von Django (ein Buch) –

5

die oben genannten Antworten Lesen, schien es, dass dieser Ansatz, während das Problem zu lösen, war im wesentlichen ein Hack alte Funktionalität zu bringen. Ein wenig googeln brachte die generic class-based views page, die einen Abschnitt mit dem Titel "adding extra context" enthält. Nur zusammenzufassen hier die Lösung einfach ist Ihre eigene Version von get_context_data() zu implementieren, die die Variablen umfassen würden Sie auf die Vorlagen übergeben möchten:

from django.views.generic import DetailView 
from books.models import Publisher, Book 

class PublisherDetail(DetailView): 

    model = Publisher 

    def get_context_data(self, **kwargs): 
     # Call the base implementation first to get a context 
     context = super(PublisherDetail, self).get_context_data(**kwargs) 
     # Add in a QuerySet of all the books 
     context['book_list'] = Book.objects.all() 
     return context 

Der größte Vorteil ist, dass Sie nicht zu „hacken“ benötigt urls.py um alle Arten von Kontextargumenten einzubeziehen, können Sie alle Funktionen nutzen, die von klassenbasierten Ansichten bereitgestellt werden, während Sie weiterhin benutzerdefinierten Kontextinhalt bereitstellen.

+0

Ist das nicht genau die akzeptierte Antwort? – fariza

+0

@fariza - Der Code ist der gleiche, der Unterschied ist der Ansatz. Die angenommene Antwort verwendet den obigen Code, um Daten an 'as_view' zu übergeben (wenn ich es richtig verstehe). Dies legt nahe, den Code zu verwenden, um die Argumente direkt an die Vorlage zu übergeben, ohne etwas in "urls.py" ändern zu müssen. – eykanal

+0

die ursprüngliche Frage war über entfernte Funktionalität und wie man es zurückbringt. Diese Funktionalität implizierte generische Ansichten, die zusätzlichen Kontext von der URLs.py akzeptiert – fariza

Verwandte Themen