Класс DateDetailView (Django 2.1)
from django.views.generic import DateDetailViewDetail view of a single object on a single date; this differs from the standard DetailView by accepting a year/month/day in the URL.
Атрибуты
| Определено в | |
|---|---|
| 
                                        allow_future = False
                                     | DateMixin | 
| 
                                        content_type = None
                                     | TemplateResponseMixin | 
| 
                                        context_object_name = None
                                     | SingleObjectMixin | 
| 
                                        date_field = None
                                     | DateMixin | 
| 
                                        day = None
                                     | DayMixin | 
| 
                                        day_format = '%d'
                                     | DayMixin | 
| 
                                        extra_context = None
                                     | ContextMixin | 
| 
                                        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
                                     | View | 
| 
                                        model = None
                                     | SingleObjectMixin | 
| 
                                        month = None
                                     | MonthMixin | 
| 
                                        month_format = '%b'
                                     | MonthMixin | 
| 
                                        pk_url_kwarg = 'pk'
                                     | SingleObjectMixin | 
| 
                                        query_pk_and_slug = False
                                     | SingleObjectMixin | 
| 
                                        queryset = None
                                     | SingleObjectMixin | 
| 
                                        response_class = <class 'django.template.response.TemplateResponse'>
                                     | TemplateResponseMixin | 
| 
                                        slug_field = 'slug'
                                     | SingleObjectMixin | 
| 
                                        slug_url_kwarg = 'slug'
                                     | SingleObjectMixin | 
| 
                                        template_engine = None
                                     | TemplateResponseMixin | 
| 
                                        template_name = None
                                     | TemplateResponseMixin | 
| 
                                        template_name_field = None
                                     | SingleObjectTemplateResponseMixin | 
| 
                                        template_name_suffix = '_detail'
                                     | SingleObjectTemplateResponseMixin | 
| 
                                        uses_datetime_field = <django.utils.functional.cached_property object at 0x7fdf2c6939e8>
                                     | DateMixin | 
| 
                                        year = None
                                     | YearMixin | 
| 
                                        year_format = '%Y'
                                     | YearMixin | 
Методы
def _allowed_methods(self):
    return [m.upper() for m in self.http_method_names if hasattr(self, m)]Основная точка входа процесса "запрос-ответ".
@classonlymethod
def as_view(cls, **initkwargs):
    """Main entry point for a request-response process."""
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError("You tried to pass in the %s method name as a "
                            "keyword argument to %s(). Don't do that."
                            % (key, cls.__name__))
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)
    view.view_class = cls
    view.view_initkwargs = initkwargs
    # take name and docstring from class
    update_wrapper(view, cls, updated=())
    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())
    return viewdef dispatch(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.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)def get(self, request, *args, **kwargs):
    self.object = self.get_object()
    context = self.get_context_data(object=self.object)
    return self.render_to_response(context)Return `True` if the view should be allowed to display objects from the future.
def get_allow_future(self):
    """
    Return `True` if the view should be allowed to display objects from
    the future.
    """
    return self.allow_futureSingleObjectMixin
Insert the single object into the context dict.
def get_context_data(self, **kwargs):
    """Insert the single object into the context dict."""
    context = {}
    if self.object:
        context['object'] = self.object
        context_object_name = self.get_context_object_name(self.object)
        if context_object_name:
            context[context_object_name] = self.object
    context.update(kwargs)
    return super().get_context_data(**context)ContextMixin
def get_context_data(self, **kwargs):
    kwargs.setdefault('view', self)
    if self.extra_context is not None:
        kwargs.update(self.extra_context)
    return kwargsGet the name to use for the object.
def get_context_object_name(self, obj):
    """Get the name to use for the object."""
    if self.context_object_name:
        return self.context_object_name
    elif isinstance(obj, models.Model):
        return obj._meta.model_name
    else:
        return NoneВозвращает дату начала текущего интервала.
def _get_current_day(self, date):
    """Return the start date of the current interval."""
    return dateВозвращает дату начала текущего интервала.
def _get_current_month(self, date):
    """Return the start date of the previous interval."""
    return date.replace(day=1)Возвращает дату начала текущего интервала.
def _get_current_year(self, date):
    """Return the start date of the current interval."""
    return date.replace(month=1, day=1)Get the name of the date field to be used to filter by.
def get_date_field(self):
    """Get the name of the date field to be used to filter by."""
    if self.date_field is None:
        raise ImproperlyConfigured("%s.date_field is required." % self.__class__.__name__)
    return self.date_fieldReturn the day for which this view should display data.
def get_day(self):
    """Return the day for which this view should display data."""
    day = self.day
    if day is None:
        try:
            day = self.kwargs['day']
        except KeyError:
            try:
                day = self.request.GET['day']
            except KeyError:
                raise Http404(_("No day specified"))
    return dayGet a day format string in strptime syntax to be used to parse the day from url variables.
def get_day_format(self):
    """
    Get a day format string in strptime syntax to be used to parse the day
    from url variables.
    """
    return self.day_formatReturn the month for which this view should display data.
def get_month(self):
    """Return the month for which this view should display data."""
    month = self.month
    if month is None:
        try:
            month = self.kwargs['month']
        except KeyError:
            try:
                month = self.request.GET['month']
            except KeyError:
                raise Http404(_("No month specified"))
    return monthGet a month format string in strptime syntax to be used to parse the month from url variables.
def get_month_format(self):
    """
    Get a month format string in strptime syntax to be used to parse the
    month from url variables.
    """
    return self.month_formatВозвращает дату начала следующего интервала. Интервал определяется датой начала <= дата элемента < следующая дата начала.
def _get_next_day(self, date):
    """
    Return the start date of the next interval.
    The interval is defined by start date <= item date < next start date.
    """
    return date + datetime.timedelta(days=1)Get the next valid day.
def get_next_day(self, date):
    """Get the next valid day."""
    return _get_next_prev(self, date, is_previous=False, period='day')Возвращает дату начала следующего интервала. Интервал определяется датой начала <= дата элемента < следующая дата начала.
def _get_next_month(self, date):
    """
    Return the start date of the next interval.
    The interval is defined by start date <= item date < next start date.
    """
    if date.month == 12:
        try:
            return date.replace(year=date.year + 1, month=1, day=1)
        except ValueError:
            raise Http404(_("Date out of range"))
    else:
        return date.replace(month=date.month + 1, day=1)Get the next valid month.
def get_next_month(self, date):
    """Get the next valid month."""
    return _get_next_prev(self, date, is_previous=False, period='month')Возвращает дату начала следующего интервала. Интервал определяется датой начала <= дата элемента < следующая дата начала.
def _get_next_year(self, date):
    """
    Return the start date of the next interval.
    The interval is defined by start date <= item date < next start date.
    """
    try:
        return date.replace(year=date.year + 1, month=1, day=1)
    except ValueError:
        raise Http404(_("Date out of range"))Get the next valid year.
def get_next_year(self, date):
    """Get the next valid year."""
    return _get_next_prev(self, date, is_previous=False, period='year')BaseDateDetailView
Get the object this request displays.
def get_object(self, queryset=None):
    """Get the object this request displays."""
    year = self.get_year()
    month = self.get_month()
    day = self.get_day()
    date = _date_from_string(year, self.get_year_format(),
                             month, self.get_month_format(),
                             day, self.get_day_format())
    # Use a custom queryset if provided
    qs = self.get_queryset() if queryset is None else queryset
    if not self.get_allow_future() and date > datetime.date.today():
        raise Http404(_(
            "Future %(verbose_name_plural)s not available because "
            "%(class_name)s.allow_future is False."
        ) % {
            'verbose_name_plural': qs.model._meta.verbose_name_plural,
            'class_name': self.__class__.__name__,
        })
    # Filter down a queryset from self.queryset using the date from the
    # URL. This'll get passed as the queryset to DetailView.get_object,
    # which'll handle the 404
    lookup_kwargs = self._make_single_date_lookup(date)
    qs = qs.filter(**lookup_kwargs)
    return super().get_object(queryset=qs)SingleObjectMixin
Return the object the view is displaying. Require `self.queryset` and a `pk` or `slug` argument in the URLconf. Subclasses can override this to return any object.
def get_object(self, queryset=None):
    """
    Return the object the view is displaying.
    Require `self.queryset` and a `pk` or `slug` argument in the URLconf.
    Subclasses can override this to return any object.
    """
    # Use a custom queryset if provided; this is required for subclasses
    # like DateDetailView
    if queryset is None:
        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)
    if pk is not None:
        queryset = queryset.filter(pk=pk)
    # Next, try looking up by slug.
    if slug is not None and (pk is None or self.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.
    if pk is None and slug is None:
        raise AttributeError(
            "Generic detail view %s must be called with either an object "
            "pk or a slug in the URLconf." % self.__class__.__name__
        )
    try:
        # Get the single item from the filtered queryset
        obj = queryset.get()
    except queryset.model.DoesNotExist:
        raise Http404(_("No %(verbose_name)s found matching the query") %
                      {'verbose_name': queryset.model._meta.verbose_name})
    return objGet the previous valid day.
def get_previous_day(self, date):
    """Get the previous valid day."""
    return _get_next_prev(self, date, is_previous=True, period='day')Get the previous valid month.
def get_previous_month(self, date):
    """Get the previous valid month."""
    return _get_next_prev(self, date, is_previous=True, period='month')Get the previous valid year.
def get_previous_year(self, date):
    """Get the previous valid year."""
    return _get_next_prev(self, date, is_previous=True, period='year')Return the `QuerySet` that will be used to look up the object. This method is called by the default implementation of get_object() and may not be called if get_object() is overridden.
def get_queryset(self):
    """
    Return the `QuerySet` that will be used to look up the object.
    This method is called by the default implementation of get_object() and
    may not be called if get_object() is overridden.
    """
    if self.queryset is None:
        if self.model:
            return self.model._default_manager.all()
        else:
            raise ImproperlyConfigured(
                "%(cls)s is missing a QuerySet. Define "
                "%(cls)s.model, %(cls)s.queryset, or override "
                "%(cls)s.get_queryset()." % {
                    'cls': self.__class__.__name__
                }
            )
    return self.queryset.all()Get the name of a slug field to be used to look up by slug.
def get_slug_field(self):
    """Get the name of a slug field to be used to look up by slug."""
    return self.slug_fieldSingleObjectTemplateResponseMixin
Return a list of template names to be used for the request. May not be called if render_to_response() is overridden. Return 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``
def get_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. Return 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().get_template_names()
    except ImproperlyConfigured:
        # 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.
        if self.object and self.template_name_field:
            name = getattr(self.object, self.template_name_field, None)
            if name:
                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.
        if isinstance(self.object, models.Model):
            object_meta = self.object._meta
            names.append("%s/%s%s.html" % (
                object_meta.app_label,
                object_meta.model_name,
                self.template_name_suffix
            ))
        elif getattr(self, 'model', None) is not None and issubclass(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.
        if not names:
            raise
    return namesTemplateResponseMixin
Return 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.
def get_template_names(self):
    """
    Return 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.
    """
    if self.template_name is None:
        raise ImproperlyConfigured(
            "TemplateResponseMixin requires either a definition of "
            "'template_name' or an implementation of 'get_template_names()'")
    else:
        return [self.template_name]Возвращает год, для которого это представление должно отображать данные.
def get_year(self):
    """Return the year for which this view should display data."""
    year = self.year
    if year is None:
        try:
            year = self.kwargs['year']
        except KeyError:
            try:
                year = self.request.GET['year']
            except KeyError:
                raise Http404(_("No year specified"))
    return yearПолучает строку в формате года в синтаксисе strptime, которая будет использоваться для анализа года по переменным URL.
def get_year_format(self):
    """
    Get a year format string in strptime syntax to be used to parse the
    year from url variables.
    """
    return self.year_formatdef http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning(
        'Method Not Allowed (%s): %s', request.method, request.path,
        extra={'status_code': 405, 'request': request}
    )
    return HttpResponseNotAllowed(self._allowed_methods())Конструктор. Вызывается в URLconf; может содержать полезные дополнительные ключевые аргументы и другие вещи.
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.
    for key, value in kwargs.items():
        setattr(self, key, value)Convert a date into a datetime when the date field is a DateTimeField. When time zone support is enabled, `date` is assumed to be in the current time zone, so that displayed items are consistent with the URL.
def _make_date_lookup_arg(self, value):
    """
    Convert a date into a datetime when the date field is a DateTimeField.
    When time zone support is enabled, `date` is assumed to be in the
    current time zone, so that displayed items are consistent with the URL.
    """
    if self.uses_datetime_field:
        value = datetime.datetime.combine(value, datetime.time.min)
        if settings.USE_TZ:
            value = timezone.make_aware(value)
    return valueGet the lookup kwargs for filtering on a single date. If the date field is a DateTimeField, we can't just filter on date_field=date because that doesn't take the time into account.
def _make_single_date_lookup(self, date):
    """
    Get the lookup kwargs for filtering on a single date.
    If the date field is a DateTimeField, we can't just filter on
    date_field=date because that doesn't take the time into account.
    """
    date_field = self.get_date_field()
    if self.uses_datetime_field:
        since = self._make_date_lookup_arg(date)
        until = self._make_date_lookup_arg(date + datetime.timedelta(days=1))
        return {
            '%s__gte' % date_field: since,
            '%s__lt' % date_field: until,
        }
    else:
        # Skip self._make_date_lookup_arg, it's a no-op in this branch.
        return {date_field: date}Обрабатывает ответы на запросы для запроса HTTP OPTIONS.
def options(self, request, *args, **kwargs):
    """Handle responding to requests for the OPTIONS HTTP verb."""
    response = HttpResponse()
    response['Allow'] = ', '.join(self._allowed_methods())
    response['Content-Length'] = '0'
    return responseВозвращает ответ (response), используя `response_class` для этого представления, с шаблоном, отображаемым с заданным контекстом. Передает response_kwargs в конструктор класса ответа.
def render_to_response(self, context, **response_kwargs):
    """
    Return a response, using the `response_class` for this view, with a
    template rendered with the given context.
    Pass response_kwargs to the constructor of the response class.
    """
    response_kwargs.setdefault('content_type', self.content_type)
    return self.response_class(
        request=self.request,
        template=self.get_template_names(),
        context=context,
        using=self.template_engine,
        **response_kwargs
    )