def__init__(self,**kwargs):""" Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things. """# Go through keyword arguments, and either save their values to our# instance, or raise an error.forkey,valueinsix.iteritems(kwargs):setattr(self,key,value)
@classonlymethoddefas_view(cls,**initkwargs):""" Main entry point for a request-response process. """forkeyininitkwargs:ifkeyincls.http_method_names:raiseTypeError("You tried to pass in the %s method name as a ""keyword argument to %s(). Don't do that."%(key,cls.__name__))ifnothasattr(cls,key):raiseTypeError("%s() received an invalid keyword %r. as_view ""only accepts arguments that are already ""attributes of the class."%(cls.__name__,key))defview(request,*args,**kwargs):self=cls(**initkwargs)ifhasattr(self,'get')andnothasattr(self,'head'):self.head=self.getself.request=requestself.args=argsself.kwargs=kwargsreturnself.dispatch(request,*args,**kwargs)view.view_class=clsview.view_initkwargs=initkwargs# take name and docstring from classupdate_wrapper(view,cls,updated=())# and possible attributes set by decorators# like csrf_exempt from dispatchupdate_wrapper(view,cls.dispatch,assigned=())returnview
80
81
82
83
84
85
86
87
88
defdispatch(self,request,*args,**kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.ifrequest.method.lower()inself.http_method_names:handler=getattr(self,request.method.lower(),self.http_method_not_allowed)else:handler=self.http_method_not_allowedreturnhandler(request,*args,**kwargs)
defget_context_data(self,**kwargs):""" Insert the single object into the context dict. """context={}ifself.object:context['object']=self.objectcontext_object_name=self.get_context_object_name(self.object)ifcontext_object_name:context[context_object_name]=self.objectcontext.update(kwargs)returnsuper(SingleObjectMixin,self).get_context_data(**context)
defget_context_object_name(self,obj):""" Get the name to use for the object. """ifself.context_object_name:returnself.context_object_nameelifisinstance(obj,models.Model):returnobj._meta.model_nameelse:returnNone
defget_object(self,queryset=None):""" Returns the object the view is displaying. By default this requires `self.queryset` and a `pk` or `slug` argument in the URLconf, but subclasses can override this to return any object. """# Use a custom queryset if provided; this is required for subclasses# like DateDetailViewifquerysetisNone:queryset=self.get_queryset()# Next, try looking up by primary key.pk=self.kwargs.get(self.pk_url_kwarg)slug=self.kwargs.get(self.slug_url_kwarg)ifpkisnotNone:queryset=queryset.filter(pk=pk)# Next, try looking up by slug.ifslugisnotNoneand(pkisNoneorself.query_pk_and_slug):slug_field=self.get_slug_field()queryset=queryset.filter(**{slug_field:slug})# If none of those are defined, it's an error.ifpkisNoneandslugisNone:raiseAttributeError("Generic detail view %s must be called with ""either an object pk or a slug."%self.__class__.__name__)try:# Get the single item from the filtered querysetobj=queryset.get()exceptqueryset.model.DoesNotExist:raiseHttp404(_("No %(verbose_name)s found matching the query")%{'verbose_name':queryset.model._meta.verbose_name})returnobj
defget_queryset(self):""" Return the `QuerySet` that will be used to look up the object. Note that this method is called by the default implementation of `get_object` and may not be called if `get_object` is overridden. """ifself.querysetisNone:ifself.model:returnself.model._default_manager.all()else:raiseImproperlyConfigured("%(cls)s is missing a QuerySet. Define ""%(cls)s.model, %(cls)s.queryset, or override ""%(cls)s.get_queryset()."%{'cls':self.__class__.__name__})returnself.queryset.all()
79
80
81
82
83
defget_slug_field(self):""" Get the name of a slug field to be used to look up by slug. """returnself.slug_field
defget_template_names(self):""" Return a list of template names to be used for the request. May not be called if render_to_response is overridden. Returns the following list: * the value of ``template_name`` on the view (if provided) * the contents of the ``template_name_field`` field on the object instance that the view is operating upon (if available) * ``<app_label>/<model_name><template_name_suffix>.html`` """try:names=super(SingleObjectTemplateResponseMixin,self).get_template_names()exceptImproperlyConfigured:# If template_name isn't specified, it's not a problem --# we just start with an empty list.names=[]# If self.template_name_field is set, grab the value of the field# of that name from the object; this is the most specific template# name, if given.ifself.objectandself.template_name_field:name=getattr(self.object,self.template_name_field,None)ifname:names.insert(0,name)# The least-specific option is the default <app>/<model>_detail.html;# only use this if the object in question is a model.ifisinstance(self.object,models.Model):object_meta=self.object._metanames.append("%s/%s%s.html"%(object_meta.app_label,object_meta.model_name,self.template_name_suffix))elifhasattr(self,'model')andself.modelisnotNoneandissubclass(self.model,models.Model):names.append("%s/%s%s.html"%(self.model._meta.app_label,self.model._meta.model_name,self.template_name_suffix))# If we still haven't managed to find any template names, we should# re-raise the ImproperlyConfigured to alert the user.ifnotnames:raisereturnnames
TemplateResponseMixin
136
137
138
139
140
141
142
143
144
145
146
defget_template_names(self):""" Returns a list of template names to be used for the request. Must return a list. May not be called if render_to_response is overridden. """ifself.template_nameisNone:raiseImproperlyConfigured("TemplateResponseMixin requires either a definition of ""'template_name' or an implementation of 'get_template_names()'")else:return[self.template_name]
90
91
92
93
94
95
defhttp_method_not_allowed(self,request,*args,**kwargs):logger.warning('Method Not Allowed (%s): %s',request.method,request.path,extra={'status_code':405,'request':request})returnhttp.HttpResponseNotAllowed(self._allowed_methods())
97
98
99
100
101
102
103
104
defoptions(self,request,*args,**kwargs):""" Handles responding to requests for the OPTIONS HTTP verb. """response=http.HttpResponse()response['Allow']=', '.join(self._allowed_methods())response['Content-Length']='0'returnresponse
defrender_to_response(self,context,**response_kwargs):""" Returns a response, using the `response_class` for this view, with a template rendered with the given context. If any keyword arguments are provided, they will be passed to the constructor of the response class. """response_kwargs.setdefault('content_type',self.content_type)returnself.response_class(request=self.request,template=self.get_template_names(),context=context,using=self.template_engine,**response_kwargs)