2016-06-04 18 views
0

Ich entwickle ein Navigationssystem, und ich brauche eine class based view von einem URI, der darauf zeigt.Wie bekomme ich in Django eine Instanz der klassenbasierten Ansicht, in die ein URI aufgelöst wird?

Wo ich gerade bin, benutze resolve('/path/to/whatever/'), um eine ResolverMatch zu bekommen. A ResolverMatch hat ein Diktat func, das auf die class based view nur als eine aufrufbare Funktion, nicht als ein Objekt verknüpft.

ResolverMatch(func=catalog.views.ThingDetail, args=(), kwargs={'id': '99'}, url_name=thing_detail, app_names=[], namespaces=[])

Was ich brauche, ist das Objekt als ein Objekt, though. Ich hacke meinen Weg durch die Verwendung von inspect, um das func Objekt zu bekommen, aber es scheint, als sollte es einen besseren Weg geben.

+0

Also wollen Sie das Klassenobjekt oder eine Instanz davon? – schwobaseggl

Antwort

0

Ich habe festgestellt, dass es eine Eigenschaft ist resolver_match.func.view_class, und ich kann resolver_match.func.view_class() rufen Sie einfach an eine Instanz der Klasse-basierten-Ansicht zu erhalten.

Dank @schwobaseggl für das Hinweis, dass resolver_match.func ein Objekt mit Eigenschaften ist. Es ist seltsam und überraschend, dass ein Objekt mit der Klasse function Eigenschaften hat.

0

Folgendes sollte arbeiten Sie die Ansichtsklasse und eine Instanz davon zu bekommen, wenn nötig:

import importlib 

rm = resolve('/path/to/whatever/') # ResolverMatch 
module_name = rm.func.__module__ # 'path.to.views' 
view_name = rm.func.func_name #'FooView' 

views = importlib.import_module(module_name) 
# <module 'path.to.views' from '/path/to/project_root/path/to/views.pyc'> 

view_klass = getattr(views, view_name) 
# <class 'path.to.views.FooView'> 

view_instance = view_klass() 
# <path.to.views.FooView object at 0x7fe2219528d0> 

Beachten Sie jedoch, dass es nicht möglich ist, die sehr Instanz zu erhalten, die für eine bestimmte Anforderung verwendet wird, Auf diese Weise wird die View-Klasse nur dann instanziiert, wenn - die aufrufbare Rückgabe von View.as_view() - aufgerufen wird.

Auszug aus implementation of View:

@classonlymethod 
def as_view(cls, **initkwargs): 
    ... 
    def view(request, *args, **kwargs): 
     # See: view cls is only instantiated when 'view' is called 
     self = cls(**initkwargs) 
     ... 
     return self.dispatch(request, *args, **kwargs) 
    ... 
    return view