Top

telemeta.admin module

# -*- coding: utf-8 -*-
from telemeta.models import *
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin

admin.site.unregister(User)

class MediaFondsAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    filter_horizontal = ['children']

class MediaCorpusAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    filter_horizontal = ['children']

class MediaCollectionRelatedInline(admin.StackedInline):
    model = MediaCollectionRelated

class MediaCollectionIdentifierInline(admin.StackedInline):
    model = MediaCollectionIdentifier
    max_num = 1

class MediaCollectionAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    inlines = [MediaCollectionIdentifierInline,
                MediaCollectionRelatedInline]

class MediaItemRelatedInline(admin.StackedInline):
    model = MediaItemRelated

class MediaItemMarkerInline(admin.StackedInline):
    model = MediaItemMarker

class MediaItemTranscodedInline(admin.StackedInline):
    model = MediaItemTranscoded

class MediaItemIdentifierInline(admin.StackedInline):
    model = MediaItemIdentifier
    max_num = 1

class MediaItemAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    exclude = ('copied_from_item', )
    inlines = [MediaItemIdentifierInline,
                MediaItemRelatedInline,
                MediaItemTranscodedInline,
                MediaItemMarkerInline]

class MediaPartAdmin(admin.ModelAdmin):
    search_fields = ['title', 'item__code']
    ordering = ['title']

class InstrumentAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

class InstrumentAliasAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

class InstrumentRelationAdmin(admin.ModelAdmin):
    search_fields = ['instrument__name', 'parent_instrument__name']
    ordering = ['parent_instrument__name']

class InstrumentAliasRelationAdmin(admin.ModelAdmin):
    search_fields = ['alias__name', 'instrument__name']
    ordering = ['alias__name']

class LocationAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

class LocationAliasAdmin(admin.ModelAdmin):
    search_fields = ['location__name', 'alias']
    ordering = ['alias']

class LocationRelationAdmin(admin.ModelAdmin):
    search_fields = ['location__name', 'ancestor_location__name']
    ordering = ['ancestor_location__name']

class LanguageAdmin(admin.ModelAdmin):
    search_fields = ['name', 'identifier']
    ordering = ['name']

class RevisionAdmin(admin.ModelAdmin):
    search_fields = ['element_id', 'user']
    ordering = ['-time']

class FormatAdmin(admin.ModelAdmin):
    search_fields = ['original_code', 'tape_reference']

class UserProfileInline(admin.StackedInline):
	model = UserProfile

class UserProfileAdmin(UserAdmin):
	inlines = [UserProfileInline]

class PlaylistAdmin(admin.ModelAdmin):
    search_fields = ['title', 'public_id']

class EnumerationPropertyAdmin(admin.ModelAdmin):
    list_display = ['enumeration_name', 'is_admin', 'is_hidden']


admin.site.register(MediaFonds, MediaFondsAdmin)
admin.site.register(MediaCorpus, MediaCorpusAdmin)
admin.site.register(MediaCollection, MediaCollectionAdmin)
admin.site.register(MediaItem, MediaItemAdmin)
admin.site.register(MediaPart, MediaPartAdmin)

admin.site.register(Instrument, InstrumentAdmin)
admin.site.register(InstrumentAlias, InstrumentAliasAdmin)
admin.site.register(InstrumentRelation, InstrumentRelationAdmin)
admin.site.register(InstrumentAliasRelation, InstrumentAliasRelationAdmin)

admin.site.register(Location, LocationAdmin)
admin.site.register(LocationType)
admin.site.register(LocationAlias, LocationAliasAdmin)
admin.site.register(LocationRelation, LocationRelationAdmin)

admin.site.register(Language, LanguageAdmin)

admin.site.register(Revision, RevisionAdmin)

admin.site.register(Format, FormatAdmin)

admin.site.register(User, UserProfileAdmin)

admin.site.register(PublisherCollection)
admin.site.register(Playlist, PlaylistAdmin)

admin.site.register(EnumerationProperty, EnumerationPropertyAdmin)

Module variables

var ITEM_PUBLIC_ACCESS_CHOICES

var ITEM_TRANSODING_STATUS

var PUBLIC_ACCESS_CHOICES

var SCOPE_CHOICES

var TYPE_CHOICES

var app_name

var code_linesep

var collection_code_regex

var collection_published_code_regex

var collection_unpublished_code_regex

var default_decoding

var default_encoding

var engine

var eol

var ext

var item_code_regex

var item_published_code_regex

var item_unpublished_code_regex

var mime_type

var private_extra_types

var public_extra_types

var resource_code_regex

var strict_code

Classes

class EnumerationPropertyAdmin

class EnumerationPropertyAdmin(admin.ModelAdmin):
    list_display = ['enumeration_name', 'is_admin', 'is_hidden']

Ancestors (in MRO)

  • EnumerationPropertyAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class FormatAdmin

class FormatAdmin(admin.ModelAdmin):
    search_fields = ['original_code', 'tape_reference']

Ancestors (in MRO)

  • FormatAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class InstrumentAdmin

class InstrumentAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

Ancestors (in MRO)

  • InstrumentAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class InstrumentAliasAdmin

class InstrumentAliasAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

Ancestors (in MRO)

  • InstrumentAliasAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class InstrumentAliasRelationAdmin

class InstrumentAliasRelationAdmin(admin.ModelAdmin):
    search_fields = ['alias__name', 'instrument__name']
    ordering = ['alias__name']

Ancestors (in MRO)

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class InstrumentRelationAdmin

class InstrumentRelationAdmin(admin.ModelAdmin):
    search_fields = ['instrument__name', 'parent_instrument__name']
    ordering = ['parent_instrument__name']

Ancestors (in MRO)

  • InstrumentRelationAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class LanguageAdmin

class LanguageAdmin(admin.ModelAdmin):
    search_fields = ['name', 'identifier']
    ordering = ['name']

Ancestors (in MRO)

  • LanguageAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class LocationAdmin

class LocationAdmin(admin.ModelAdmin):
    search_fields = ['name']
    ordering = ['name']

Ancestors (in MRO)

  • LocationAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class LocationAliasAdmin

class LocationAliasAdmin(admin.ModelAdmin):
    search_fields = ['location__name', 'alias']
    ordering = ['alias']

Ancestors (in MRO)

  • LocationAliasAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class LocationRelationAdmin

class LocationRelationAdmin(admin.ModelAdmin):
    search_fields = ['location__name', 'ancestor_location__name']
    ordering = ['ancestor_location__name']

Ancestors (in MRO)

  • LocationRelationAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaCollectionAdmin

class MediaCollectionAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    inlines = [MediaCollectionIdentifierInline,
                MediaCollectionRelatedInline]

Ancestors (in MRO)

  • MediaCollectionAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaCollectionIdentifierInline

class MediaCollectionIdentifierInline(admin.StackedInline):
    model = MediaCollectionIdentifier
    max_num = 1

Ancestors (in MRO)

  • MediaCollectionIdentifierInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaCollectionRelatedInline

class MediaCollectionRelatedInline(admin.StackedInline):
    model = MediaCollectionRelated

Ancestors (in MRO)

  • MediaCollectionRelatedInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaCorpusAdmin

class MediaCorpusAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    filter_horizontal = ['children']

Ancestors (in MRO)

  • MediaCorpusAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaFondsAdmin

class MediaFondsAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    filter_horizontal = ['children']

Ancestors (in MRO)

  • MediaFondsAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaItemAdmin

class MediaItemAdmin(admin.ModelAdmin):
    search_fields = ['title', 'code']
    ordering = ['code']
    exclude = ('copied_from_item', )
    inlines = [MediaItemIdentifierInline,
                MediaItemRelatedInline,
                MediaItemTranscodedInline,
                MediaItemMarkerInline]

Ancestors (in MRO)

  • MediaItemAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaItemIdentifierInline

class MediaItemIdentifierInline(admin.StackedInline):
    model = MediaItemIdentifier
    max_num = 1

Ancestors (in MRO)

  • MediaItemIdentifierInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaItemMarkerInline

class MediaItemMarkerInline(admin.StackedInline):
    model = MediaItemMarker

Ancestors (in MRO)

  • MediaItemMarkerInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaItemRelatedInline

class MediaItemRelatedInline(admin.StackedInline):
    model = MediaItemRelated

Ancestors (in MRO)

  • MediaItemRelatedInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaItemTranscodedInline

class MediaItemTranscodedInline(admin.StackedInline):
    model = MediaItemTranscoded

Ancestors (in MRO)

  • MediaItemTranscodedInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class MediaPartAdmin

class MediaPartAdmin(admin.ModelAdmin):
    search_fields = ['title', 'item__code']
    ordering = ['title']

Ancestors (in MRO)

  • MediaPartAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class PlaylistAdmin

class PlaylistAdmin(admin.ModelAdmin):
    search_fields = ['title', 'public_id']

Ancestors (in MRO)

  • PlaylistAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class RevisionAdmin

class RevisionAdmin(admin.ModelAdmin):
    search_fields = ['element_id', 'user']
    ordering = ['-time']

Ancestors (in MRO)

  • RevisionAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_form_template

var change_form_template

var change_list_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

The 'add' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

Hook for specifying fieldsets for the add form.

def get_fieldsets(self, request, obj=None):
    "Hook for specifying fieldsets for the add form."
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_form(request, obj, fields=None)
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_form(

self, request, obj=None, **kwargs)

Returns a Form class for use in the admin add view. This is used by add_view and change_view.

def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # ModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # if exclude is an empty list we pass None to be consistent with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    try:
        return modelform_factory(self.model, **defaults)
    except FieldError as e:
        raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
                         % (e, self.__class__.__name__))

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns, url
    def wrap(view):
        def wrapper(*args, **kwargs):
            return self.admin_site.admin_view(view)(*args, **kwargs)
        return update_wrapper(wrapper, view)
    info = self.model._meta.app_label, self.model._meta.model_name
    urlpatterns = patterns('',
        url(r'^$',
            wrap(self.changelist_view),
            name='%s_%s_changelist' % info),
        url(r'^add/$',
            wrap(self.add_view),
            name='%s_%s_add' % info),
        url(r'^(.+)/history/$',
            wrap(self.history_view),
            name='%s_%s_history' % info),
        url(r'^(.+)/delete/$',
            wrap(self.delete_view),
            name='%s_%s_delete' % info),
        url(r'^(.+)/$',
            wrap(self.change_view),
            name='%s_%s_change' % info),
    )
    return urlpatterns

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage.
    """
    opts = obj._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    # Here, we distinguish between different save types by checking for
    # the presence of keys in request.POST.
    if IS_POPUP_VAR in request.POST:
        return SimpleTemplateResponse('admin/popup_response.html', {
            'pk_value': escape(pk_value),
            'obj': escapejs(obj)
        })
    elif "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        if post_url_continue is None:
            post_url_continue = reverse('admin:%s_%s_change' %
                                        (opts.app_label, opts.model_name),
                                        args=(pk_value,),
                                        current_app=self.admin_site.name)
        post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
        return HttpResponseRedirect(post_url_continue)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was added successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_add(request, obj)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class UserProfileAdmin

class UserProfileAdmin(UserAdmin):
	inlines = [UserProfileInline]

Ancestors (in MRO)

  • UserProfileAdmin
  • django.contrib.auth.admin.UserAdmin
  • django.contrib.admin.options.ModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var action_form

var actions

var actions_on_bottom

var actions_on_top

var actions_selection_counter

var add_fieldsets

var add_form

var add_form_template

var change_form_template

var change_list_template

var change_password_form

var change_user_password_template

var date_hierarchy

var delete_confirmation_template

var delete_selected_confirmation_template

var exclude

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var form

var formfield_overrides

var inlines

var list_display

var list_editable

var list_filter

var list_max_show_all

var list_per_page

var object_history_template

var ordering

var paginator

var prepopulated_fields

var preserve_filters

var radio_fields

var raw_id_fields

var readonly_fields

var save_as

var save_on_top

var search_fields

var validator_class

Instance variables

var declared_fieldsets

var media

var urls

Methods

def __init__(

self, model, admin_site)

def __init__(self, model, admin_site):
    self.model = model
    self.opts = model._meta
    self.admin_site = admin_site
    super(ModelAdmin, self).__init__()

def action_checkbox(

self, obj)

A list_display column containing a checkbox widget.

def action_checkbox(self, obj):
    """
    A list_display column containing a checkbox widget.
    """
    return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk))

def add_view(

self, *args, **kwargs)

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def change_view(

self, *args, **kwargs)

The 'change' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def changelist_view(

self, *args, **kwargs)

The 'change list' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def construct_change_message(

self, request, form, formsets)

Construct a change message from a changed object.

def construct_change_message(self, request, form, formsets):
    """
    Construct a change message from a changed object.
    """
    change_message = []
    if form.changed_data:
        change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
    if formsets:
        for formset in formsets:
            for added_object in formset.new_objects:
                change_message.append(_('Added %(name)s "%(object)s".')
                                      % {'name': force_text(added_object._meta.verbose_name),
                                         'object': force_text(added_object)})
            for changed_object, changed_fields in formset.changed_objects:
                change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
                                      % {'list': get_text_list(changed_fields, _('and')),
                                         'name': force_text(changed_object._meta.verbose_name),
                                         'object': force_text(changed_object)})
            for deleted_object in formset.deleted_objects:
                change_message.append(_('Deleted %(name)s "%(object)s".')
                                      % {'name': force_text(deleted_object._meta.verbose_name),
                                         'object': force_text(deleted_object)})
    change_message = ' '.join(change_message)
    return change_message or _('No fields changed.')

def delete_model(

self, request, obj)

Given a model instance delete it from the database.

def delete_model(self, request, obj):
    """
    Given a model instance delete it from the database.
    """
    obj.delete()

def delete_view(

self, *args, **kwargs)

The 'delete' admin view for this model.

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_action(

self, action)

Return a given action from a parameter, which can either be a callable, or the name of a method on the ModelAdmin. Return is a tuple of (callable, name, description).

def get_action(self, action):
    """
    Return a given action from a parameter, which can either be a callable,
    or the name of a method on the ModelAdmin.  Return is a tuple of
    (callable, name, description).
    """
    # If the action is a callable, just use it.
    if callable(action):
        func = action
        action = action.__name__
    # Next, look for a method. Grab it off self.__class__ to get an unbound
    # method instead of a bound one; this ensures that the calling
    # conventions are the same for functions and methods.
    elif hasattr(self.__class__, action):
        func = getattr(self.__class__, action)
    # Finally, look for a named method on the admin site
    else:
        try:
            func = self.admin_site.get_action(action)
        except KeyError:
            return None
    if hasattr(func, 'short_description'):
        description = func.short_description
    else:
        description = capfirst(action.replace('_', ' '))
    return func, action, description

def get_action_choices(

self, request, default_choices=[(u'', u'---------')])

Return a list of choices for use in a form object. Each choice is a tuple (name, description).

def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
    """
    Return a list of choices for use in a form object.  Each choice is a
    tuple (name, description).
    """
    choices = [] + default_choices
    for func, name, description in six.itervalues(self.get_actions(request)):
        choice = (name, description % model_format_dict(self.opts))
        choices.append(choice)
    return choices

def get_actions(

self, request)

Return a dictionary mapping the names of all actions for this ModelAdmin to a tuple of (callable, name, description) for each action.

def get_actions(self, request):
    """
    Return a dictionary mapping the names of all actions for this
    ModelAdmin to a tuple of (callable, name, description) for each action.
    """
    # If self.actions is explicitly set to None that means that we don't
    # want *any* actions enabled on this page.
    from django.contrib.admin.views.main import _is_changelist_popup
    if self.actions is None or _is_changelist_popup(request):
        return SortedDict()
    actions = []
    # Gather actions from the admin site first
    for (name, func) in self.admin_site.actions:
        description = getattr(func, 'short_description', name.replace('_', ' '))
        actions.append((func, name, description))
    # Then gather them from the model admin and all parent classes,
    # starting with self and working back up.
    for klass in self.__class__.mro()[::-1]:
        class_actions = getattr(klass, 'actions', [])
        # Avoid trying to iterate over None
        if not class_actions:
            continue
        actions.extend([self.get_action(action) for action in class_actions])
    # get_action might have returned None, so filter any of those out.
    actions = filter(None, actions)
    # Convert the actions into a SortedDict keyed by name.
    actions = SortedDict([
        (name, (func, name, desc))
        for func, name, desc in actions
    ])
    return actions

def get_changelist(

self, request, **kwargs)

Returns the ChangeList class for use on the changelist page.

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    from django.contrib.admin.views.main import ChangeList
    return ChangeList

def get_changelist_form(

self, request, **kwargs)

Returns a Form class for use in the Formset on the changelist page.

def get_changelist_form(self, request, **kwargs):
    """
    Returns a Form class for use in the Formset on the changelist page.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    if (defaults.get('fields') is None
        and not modelform_defines_fields(defaults.get('form'))):
        defaults['fields'] = forms.ALL_FIELDS
    return modelform_factory(self.model, **defaults)

def get_changelist_formset(

self, request, **kwargs)

Returns a FormSet class for use on the changelist page if list_editable is used.

def get_changelist_formset(self, request, **kwargs):
    """
    Returns a FormSet class for use on the changelist page if list_editable
    is used.
    """
    defaults = {
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelformset_factory(self.model,
        self.get_changelist_form(request), extra=0,
        fields=self.list_editable, **defaults)

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if not obj:
        return self.add_fieldsets
    return super(UserAdmin, self).get_fieldsets(request, obj)

def get_form(

self, request, obj=None, **kwargs)

Use special form during user creation

def get_form(self, request, obj=None, **kwargs):
    """
    Use special form during user creation
    """
    defaults = {}
    if obj is None:
        defaults.update({
            'form': self.add_form,
            'fields': admin.util.flatten_fieldsets(self.add_fieldsets),
        })
    defaults.update(kwargs)
    return super(UserAdmin, self).get_form(request, obj, **defaults)

def get_formsets(

self, request, obj=None)

def get_formsets(self, request, obj=None):
    for inline in self.get_inline_instances(request, obj):
        yield inline.get_formset(request, obj)

def get_inline_instances(

self, request, obj=None)

def get_inline_instances(self, request, obj=None):
    inline_instances = []
    for inline_class in self.inlines:
        inline = inline_class(self.model, self.admin_site)
        if request:
            if not (inline.has_add_permission(request) or
                    inline.has_change_permission(request, obj) or
                    inline.has_delete_permission(request, obj)):
                continue
            if not inline.has_add_permission(request):
                inline.max_num = 0
        inline_instances.append(inline)
    return inline_instances

def get_list_display(

self, request)

Return a sequence containing the fields to be displayed on the changelist.

def get_list_display(self, request):
    """
    Return a sequence containing the fields to be displayed on the
    changelist.
    """
    return self.list_display

Return a sequence containing the fields to be displayed as links on the changelist. The list_display parameter is the list of fields returned by get_list_display().

def get_list_filter(

self, request)

Returns a sequence containing the fields to be displayed as filters in the right sidebar of the changelist page.

def get_list_filter(self, request):
    """
    Returns a sequence containing the fields to be displayed as filters in
    the right sidebar of the changelist page.
    """
    return self.list_filter

def get_model_perms(

self, request)

Returns a dict of all perms for this model. This dict has the keys add, change, and delete mapping to the True/False for each of those actions.

def get_model_perms(self, request):
    """
    Returns a dict of all perms for this model. This dict has the keys
    ``add``, ``change``, and ``delete`` mapping to the True/False for each
    of those actions.
    """
    return {
        'add': self.has_add_permission(request),
        'change': self.has_change_permission(request),
        'delete': self.has_delete_permission(request),
    }

def get_object(

self, request, object_id)

Returns an instance matching the primary key provided. None is returned if no match is found (or the object_id failed validation against the primary key field).

def get_object(self, request, object_id):
    """
    Returns an instance matching the primary key provided. ``None``  is
    returned if no match is found (or the object_id failed validation
    against the primary key field).
    """
    queryset = self.get_queryset(request)
    model = queryset.model
    try:
        object_id = model._meta.pk.to_python(object_id)
        return queryset.get(pk=object_id)
    except (model.DoesNotExist, ValidationError, ValueError):
        return None

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_paginator(

self, request, queryset, per_page, orphans=0, allow_empty_first_page=True)

def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    return self.paginator(queryset, per_page, orphans, allow_empty_first_page)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_preserved_filters(

self, request)

Returns the preserved filters querystring.

def get_preserved_filters(self, request):
    """
    Returns the preserved filters querystring.
    """
    match = request.resolver_match
    if self.preserve_filters and match:
        opts = self.model._meta
        current_url = '%s:%s' % (match.app_name, match.url_name)
        changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name)
        if current_url == changelist_url:
            preserved_filters = request.GET.urlencode()
        else:
            preserved_filters = request.GET.get('_changelist_filters')
        if preserved_filters:
            return urlencode({'_changelist_filters': preserved_filters})
    return ''

def get_queryset(

self, request)

Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

def get_queryset(self, request):
    """
    Returns a QuerySet of all model instances that can be edited by the
    admin site. This is used by changelist_view.
    """
    qs = self.model._default_manager.get_queryset()
    # TODO: this should be handled by some parameter to the ChangeList.
    ordering = self.get_ordering(request)
    if ordering:
        qs = qs.order_by(*ordering)
    return qs

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def get_search_results(

self, request, queryset, search_term)

Returns a tuple containing a queryset to implement the search, and a boolean indicating if the results may contain duplicates.

def get_search_results(self, request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name
    use_distinct = False
    if self.search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in self.search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(self.opts, search_spec):
                    use_distinct = True
                    break
    return queryset, use_distinct

def get_urls(

self)

def get_urls(self):
    from django.conf.urls import patterns
    return patterns('',
        (r'^(\d+)/password/$',
         self.admin_site.admin_view(self.user_change_password))
    ) + super(UserAdmin, self).get_urls()

def has_add_permission(

self, request)

Returns True if the given request has permission to add an object. Can be overridden by the user in subclasses.

def has_add_permission(self, request):
    """
    Returns True if the given request has permission to add an object.
    Can be overridden by the user in subclasses.
    """
    opts = self.opts
    codename = get_permission_codename('add', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

def has_change_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to change the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to change *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

Returns True if the given request has permission to change the given Django model instance, the default implementation doesn't examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

def has_delete_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change the given
    Django model instance, the default implementation doesn't examine the
    `obj` parameter.
    Can be overridden by the user in subclasses. In such case it should
    return True if the given request has permission to delete the `obj`
    model instance. If `obj` is None, this should return True if the given
    request has permission to delete *any* object of the given type.
    """
    opts = self.opts
    codename = get_permission_codename('delete', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def history_view(

self, request, object_id, extra_context=None)

The 'history' admin view for this model.

def history_view(self, request, object_id, extra_context=None):
    "The 'history' admin view for this model."
    from django.contrib.admin.models import LogEntry
    # First check if the user can see this history.
    model = self.model
    obj = get_object_or_404(model, pk=unquote(object_id))
    if not self.has_change_permission(request, obj):
        raise PermissionDenied
    # Then get the history for this object.
    opts = model._meta
    app_label = opts.app_label
    action_list = LogEntry.objects.filter(
        object_id=unquote(object_id),
        content_type__id__exact=ContentType.objects.get_for_model(model).id
    ).select_related().order_by('action_time')
    context = {
        'title': _('Change history: %s') % force_text(obj),
        'action_list': action_list,
        'module_name': capfirst(force_text(opts.verbose_name_plural)),
        'object': obj,
        'app_label': app_label,
        'opts': opts,
        'preserved_filters': self.get_preserved_filters(request),
    }
    context.update(extra_context or {})
    return TemplateResponse(request, self.object_history_template or [
        "admin/%s/%s/object_history.html" % (app_label, opts.model_name),
        "admin/%s/object_history.html" % app_label,
        "admin/object_history.html"
    ], context, current_app=self.admin_site.name)

def log_addition(

self, request, object)

Log that an object has been successfully added.

The default implementation creates an admin LogEntry object.

def log_addition(self, request, object):
    """
    Log that an object has been successfully added.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, ADDITION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=ADDITION
    )

def log_change(

self, request, object, message)

Log that an object has been successfully changed.

The default implementation creates an admin LogEntry object.

def log_change(self, request, object, message):
    """
    Log that an object has been successfully changed.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, CHANGE
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(object).pk,
        object_id=object.pk,
        object_repr=force_text(object),
        action_flag=CHANGE,
        change_message=message
    )

def log_deletion(

self, request, object, object_repr)

Log that an object will be deleted. Note that this method is called before the deletion.

The default implementation creates an admin LogEntry object.

def log_deletion(self, request, object, object_repr):
    """
    Log that an object will be deleted. Note that this method is called
    before the deletion.
    The default implementation creates an admin LogEntry object.
    """
    from django.contrib.admin.models import LogEntry, DELETION
    LogEntry.objects.log_action(
        user_id=request.user.pk,
        content_type_id=ContentType.objects.get_for_model(self.model).pk,
        object_id=object.pk,
        object_repr=object_repr,
        action_flag=DELETION
    )

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    # See #20078: we don't want to allow any lookups involving passwords.
    if lookup.startswith('password'):
        return False
    return super(UserAdmin, self).lookup_allowed(lookup, value)

def message_user(

self, request, message, level=20, extra_tags='', fail_silently=False)

Send a message to the user. The default implementation posts a message using the django.contrib.messages backend.

Exposes almost the same API as messages.add_message(), but accepts the positional arguments in a different order to maintain backwards compatibility. For convenience, it accepts the level argument as a string rather than the usual level number.

def message_user(self, request, message, level=messages.INFO, extra_tags='',
                 fail_silently=False):
    """
    Send a message to the user. The default implementation
    posts a message using the django.contrib.messages backend.
    Exposes almost the same API as messages.add_message(), but accepts the
    positional arguments in a different order to maintain backwards
    compatibility. For convenience, it accepts the `level` argument as
    a string rather than the usual level number.
    """
    if not isinstance(level, int):
        # attempt to get the level if passed a string
        try:
            level = getattr(messages.constants, level.upper())
        except AttributeError:
            levels = messages.constants.DEFAULT_TAGS.values()
            levels_repr = ', '.join('`%s`' % l for l in levels)
            raise ValueError('Bad message level string: `%s`. '
                    'Possible values are: %s' % (level, levels_repr))
    messages.add_message(request, level, message, extra_tags=extra_tags,
            fail_silently=fail_silently)

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def render_change_form(

self, request, context, add=False, change=False, form_url='', obj=None)

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    opts = self.model._meta
    app_label = opts.app_label
    preserved_filters = self.get_preserved_filters(request)
    form_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, form_url)
    context.update({
        'add': add,
        'change': change,
        'has_add_permission': self.has_add_permission(request),
        'has_change_permission': self.has_change_permission(request, obj),
        'has_delete_permission': self.has_delete_permission(request, obj),
        'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
        'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
        'form_url': form_url,
        'opts': opts,
        'content_type_id': ContentType.objects.get_for_model(self.model).id,
        'save_as': self.save_as,
        'save_on_top': self.save_on_top,
    })
    if add and self.add_form_template is not None:
        form_template = self.add_form_template
    else:
        form_template = self.change_form_template
    return TemplateResponse(request, form_template or [
        "admin/%s/%s/change_form.html" % (app_label, opts.model_name),
        "admin/%s/change_form.html" % app_label,
        "admin/change_form.html"
    ], context, current_app=self.admin_site.name)

def response_action(

self, request, queryset)

Handle an admin action. This is called if a request is POSTed to the changelist; it returns an HttpResponse if the action was handled, and None otherwise.

def response_action(self, request, queryset):
    """
    Handle an admin action. This is called if a request is POSTed to the
    changelist; it returns an HttpResponse if the action was handled, and
    None otherwise.
    """
    # There can be multiple action forms on the page (at the top
    # and bottom of the change list, for example). Get the action
    # whose button was pushed.
    try:
        action_index = int(request.POST.get('index', 0))
    except ValueError:
        action_index = 0
    # Construct the action form.
    data = request.POST.copy()
    data.pop(helpers.ACTION_CHECKBOX_NAME, None)
    data.pop("index", None)
    # Use the action whose button was pushed
    try:
        data.update({'action': data.getlist('action')[action_index]})
    except IndexError:
        # If we didn't get an action from the chosen form that's invalid
        # POST data, so by deleting action it'll fail the validation check
        # below. So no need to do anything here
        pass
    action_form = self.action_form(data, auto_id=None)
    action_form.fields['action'].choices = self.get_action_choices(request)
    # If the form's valid we can handle the action.
    if action_form.is_valid():
        action = action_form.cleaned_data['action']
        select_across = action_form.cleaned_data['select_across']
        func = self.get_actions(request)[action][0]
        # Get the list of selected PKs. If nothing's selected, we can't
        # perform an action on it, so bail. Except we want to perform
        # the action explicitly on all objects.
        selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
        if not selected and not select_across:
            # Reminder that something needs to be selected or nothing will happen
            msg = _("Items must be selected in order to perform "
                    "actions on them. No items have been changed.")
            self.message_user(request, msg, messages.WARNING)
            return None
        if not select_across:
            # Perform the action only on the selected objects
            queryset = queryset.filter(pk__in=selected)
        response = func(self, request, queryset)
        # Actions may return an HttpResponse-like object, which will be
        # used as the response from the POST. If not, we'll be a good
        # little HTTP citizen and redirect back to the changelist page.
        if isinstance(response, HttpResponseBase):
            return response
        else:
            return HttpResponseRedirect(request.get_full_path())
    else:
        msg = _("No action selected.")
        self.message_user(request, msg, messages.WARNING)
        return None

def response_add(

self, request, obj, post_url_continue=None)

Determines the HttpResponse for the add_view stage. It mostly defers to its superclass implementation but is customized because the User model has a slightly different workflow.

def response_add(self, request, obj, post_url_continue=None):
    """
    Determines the HttpResponse for the add_view stage. It mostly defers to
    its superclass implementation but is customized because the User model
    has a slightly different workflow.
    """
    # We should allow further modification of the user just added i.e. the
    # 'Save' button should behave like the 'Save and continue editing'
    # button except in two scenarios:
    # * The user has pressed the 'Save and add another' button
    # * We are adding a user in a popup
    if '_addanother' not in request.POST and IS_POPUP_VAR not in request.POST:
        request.POST['_continue'] = 1
    return super(UserAdmin, self).response_add(request, obj,
                                               post_url_continue)

def response_change(

self, request, obj)

Determines the HttpResponse for the change_view stage.

def response_change(self, request, obj):
    """
    Determines the HttpResponse for the change_view stage.
    """
    opts = self.model._meta
    pk_value = obj._get_pk_val()
    preserved_filters = self.get_preserved_filters(request)
    msg_dict = {'name': force_text(opts.verbose_name), 'obj': force_text(obj)}
    if "_continue" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = request.path
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_saveasnew" in request.POST:
        msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_change' %
                               (opts.app_label, opts.model_name),
                               args=(pk_value,),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    elif "_addanother" in request.POST:
        msg = _('The %(name)s "%(obj)s" was changed successfully. You may add another %(name)s below.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        redirect_url = reverse('admin:%s_%s_add' %
                               (opts.app_label, opts.model_name),
                               current_app=self.admin_site.name)
        redirect_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, redirect_url)
        return HttpResponseRedirect(redirect_url)
    else:
        msg = _('The %(name)s "%(obj)s" was changed successfully.') % msg_dict
        self.message_user(request, msg, messages.SUCCESS)
        return self.response_post_save_change(request, obj)

def response_post_save_add(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when adding a new object.

def response_post_save_add(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when adding a new object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def response_post_save_change(

self, request, obj)

Figure out where to redirect after the 'Save' button has been pressed when editing an existing object.

def response_post_save_change(self, request, obj):
    """
    Figure out where to redirect after the 'Save' button has been pressed
    when editing an existing object.
    """
    opts = self.model._meta
    if self.has_change_permission(request, None):
        post_url = reverse('admin:%s_%s_changelist' %
                           (opts.app_label, opts.model_name),
                           current_app=self.admin_site.name)
        preserved_filters = self.get_preserved_filters(request)
        post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
    else:
        post_url = reverse('admin:index',
                           current_app=self.admin_site.name)
    return HttpResponseRedirect(post_url)

def save_form(

self, request, form, change)

Given a ModelForm return an unsaved instance. change is True if the object is being changed, and False if it's being added.

def save_form(self, request, form, change):
    """
    Given a ModelForm return an unsaved instance. ``change`` is True if
    the object is being changed, and False if it's being added.
    """
    return form.save(commit=False)

def save_formset(

self, request, form, formset, change)

Given an inline formset save it to the database.

def save_formset(self, request, form, formset, change):
    """
    Given an inline formset save it to the database.
    """
    formset.save()

def save_model(

self, request, obj, form, change)

Given a model instance save it to the database.

def save_model(self, request, obj, form, change):
    """
    Given a model instance save it to the database.
    """
    obj.save()

Given the HttpRequest, the parent ModelForm instance, the list of inline formsets and a boolean value based on whether the parent is being added or changed, save the related objects to the database. Note that at this point save_form() and save_model() have already been called.

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def user_change_password(

self, *args, **kwargs)

def _wrapper(self, *args, **kwargs):
    @decorator
    def bound_func(*args2, **kwargs2):
        return func(self, *args2, **kwargs2)
    # bound_func has the signature that 'decorator' expects i.e.  no
    # 'self' argument, but it is a closure over self so it can call
    # 'func' correctly.
    return bound_func(*args, **kwargs)

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)

class UserProfileInline

class UserProfileInline(admin.StackedInline):
	model = UserProfile

Ancestors (in MRO)

  • UserProfileInline
  • django.contrib.admin.options.StackedInline
  • django.contrib.admin.options.InlineModelAdmin
  • django.contrib.admin.options.BaseModelAdmin
  • __builtin__.object

Class variables

var can_delete

var exclude

var extra

var fields

var fieldsets

var filter_horizontal

var filter_vertical

var fk_name

var form

var formfield_overrides

var formset

var max_num

var model

var ordering

var prepopulated_fields

var radio_fields

var raw_id_fields

var readonly_fields

var template

var validator_class

var verbose_name

var verbose_name_plural

Instance variables

var declared_fieldsets

var media

Methods

def __init__(

self, parent_model, admin_site)

def __init__(self, parent_model, admin_site):
    self.admin_site = admin_site
    self.parent_model = parent_model
    self.opts = self.model._meta
    super(InlineModelAdmin, self).__init__()
    if self.verbose_name is None:
        self.verbose_name = self.model._meta.verbose_name
    if self.verbose_name_plural is None:
        self.verbose_name_plural = self.model._meta.verbose_name_plural

def formfield_for_choice_field(

self, db_field, request=None, **kwargs)

Get a form Field for a database Field that has declared choices.

def formfield_for_choice_field(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a database Field that has declared choices.
    """
    # If the field is named as a radio_field, use a RadioSelect
    if db_field.name in self.radio_fields:
        # Avoid stomping on custom widget/choices arguments.
        if 'widget' not in kwargs:
            kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                'class': get_ul_class(self.radio_fields[db_field.name]),
            })
        if 'choices' not in kwargs:
            kwargs['choices'] = db_field.get_choices(
                include_blank=db_field.blank,
                blank_choice=[('', _('None'))]
            )
    return db_field.formfield(**kwargs)

def formfield_for_dbfield(

self, db_field, **kwargs)

Hook for specifying the form Field instance for a given database Field instance.

If kwargs are given, they're passed to the form Field's constructor.

def formfield_for_dbfield(self, db_field, **kwargs):
    """
    Hook for specifying the form Field instance for a given database Field
    instance.
    If kwargs are given, they're passed to the form Field's constructor.
    """
    request = kwargs.pop("request", None)
    # If the field specifies choices, we don't need to look for special
    # admin widgets - we just need to use a select widget of some kind.
    if db_field.choices:
        return self.formfield_for_choice_field(db_field, request, **kwargs)
    # ForeignKey or ManyToManyFields
    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        # Combine the field kwargs with any options for formfield_overrides.
        # Make sure the passed in **kwargs override anything in
        # formfield_overrides because **kwargs is more specific, and should
        # always win.
        if db_field.__class__ in self.formfield_overrides:
            kwargs = dict(self.formfield_overrides[db_field.__class__], **kwargs)
        # Get the correct formfield.
        if isinstance(db_field, models.ForeignKey):
            formfield = self.formfield_for_foreignkey(db_field, request, **kwargs)
        elif isinstance(db_field, models.ManyToManyField):
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)
        # For non-raw_id fields, wrap the widget with a wrapper that adds
        # extra HTML -- the "add other" interface -- to the end of the
        # rendered output. formfield can be None if it came from a
        # OneToOneField with parent_link=True or a M2M intermediary.
        if formfield and db_field.name not in self.raw_id_fields:
            related_modeladmin = self.admin_site._registry.get(
                                                        db_field.rel.to)
            can_add_related = bool(related_modeladmin and
                        related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site,
                        can_add_related=can_add_related)
        return formfield
    # If we've got overrides for the formfield defined, use 'em. **kwargs
    # passed to formfield_for_dbfield override the defaults.
    for klass in db_field.__class__.mro():
        if klass in self.formfield_overrides:
            kwargs = dict(copy.deepcopy(self.formfield_overrides[klass]), **kwargs)
            return db_field.formfield(**kwargs)
    # For any other type of field, just call its formfield() method.
    return db_field.formfield(**kwargs)

def formfield_for_foreignkey(

self, db_field, request=None, **kwargs)

Get a form Field for a ForeignKey.

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ForeignKey.
    """
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
    elif db_field.name in self.radio_fields:
        kwargs['widget'] = widgets.AdminRadioSelect(attrs={
            'class': get_ul_class(self.radio_fields[db_field.name]),
        })
        kwargs['empty_label'] = _('None') if db_field.blank else None
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def formfield_for_manytomany(

self, db_field, request=None, **kwargs)

Get a form Field for a ManyToManyField.

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    """
    Get a form Field for a ManyToManyField.
    """
    # If it uses an intermediary model that isn't auto created, don't show
    # a field in admin.
    if not db_field.rel.through._meta.auto_created:
        return None
    db = kwargs.get('using')
    if db_field.name in self.raw_id_fields:
        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel,
                                self.admin_site, using=db)
        kwargs['help_text'] = ''
    elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    if not 'queryset' in kwargs:
        queryset = self.get_field_queryset(db, db_field, request)
        if queryset is not None:
            kwargs['queryset'] = queryset
    return db_field.formfield(**kwargs)

def get_extra(

self, request, obj=None, **kwargs)

Hook for customizing the number of extra inline forms.

def get_extra(self, request, obj=None, **kwargs):
    """Hook for customizing the number of extra inline forms."""
    return self.extra

def get_field_queryset(

self, db, db_field, request)

If the ModelAdmin specifies ordering, the queryset should respect that ordering. Otherwise don't specify the queryset, let the field decide (returns None in that case).

def get_field_queryset(self, db, db_field, request):
    """
    If the ModelAdmin specifies ordering, the queryset should respect that
    ordering.  Otherwise don't specify the queryset, let the field decide
    (returns None in that case).
    """
    related_admin = self.admin_site._registry.get(db_field.rel.to, None)
    if related_admin is not None:
        ordering = related_admin.get_ordering(request)
        if ordering is not None and ordering != ():
            return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
    return None

def get_fieldsets(

self, request, obj=None)

def get_fieldsets(self, request, obj=None):
    if self.declared_fieldsets:
        return self.declared_fieldsets
    form = self.get_formset(request, obj, fields=None).form
    fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
    return [(None, {'fields': fields})]

def get_formset(

self, request, obj=None, **kwargs)

Returns a BaseInlineFormSet class for use in admin add/change views.

def get_formset(self, request, obj=None, **kwargs):
    """Returns a BaseInlineFormSet class for use in admin add/change views."""
    if 'fields' in kwargs:
        fields = kwargs.pop('fields')
    else:
        fields = flatten_fieldsets(self.get_fieldsets(request, obj))
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(self.get_readonly_fields(request, obj))
    if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude:
        # Take the custom ModelForm's Meta.exclude into account only if the
        # InlineModelAdmin doesn't define its own.
        exclude.extend(self.form._meta.exclude)
    # If exclude is an empty list we use None, since that's the actual
    # default.
    exclude = exclude or None
    can_delete = self.can_delete and self.has_delete_permission(request, obj)
    defaults = {
        "form": self.form,
        "formset": self.formset,
        "fk_name": self.fk_name,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": partial(self.formfield_for_dbfield, request=request),
        "extra": self.get_extra(request, obj, **kwargs),
        "max_num": self.get_max_num(request, obj, **kwargs),
        "can_delete": can_delete,
    }
    defaults.update(kwargs)
    base_model_form = defaults['form']
    class DeleteProtectedModelForm(base_model_form):
        def hand_clean_DELETE(self):
            """
            We don't validate the 'DELETE' field itself because on
            templates it's not rendered using the field information, but
            just using a generic "deletion_field" of the InlineModelAdmin.
            """
            if self.cleaned_data.get(DELETION_FIELD_NAME, False):
                using = router.db_for_write(self._meta.model)
                collector = NestedObjects(using=using)
                collector.collect([self.instance])
                if collector.protected:
                    objs = []
                    for p in collector.protected:
                        objs.append(
                            # Translators: Model verbose name and instance representation, suitable to be an item in a list
                            _('%(class_name)s %(instance)s') % {
                                'class_name': p._meta.verbose_name,
                                'instance': p}
                        )
                    params = {'class_name': self._meta.model._meta.verbose_name,
                              'instance': self.instance,
                              'related_objects': get_text_list(objs, _('and'))}
                    msg = _("Deleting %(class_name)s %(instance)s would require "
                            "deleting the following protected related objects: "
                            "%(related_objects)s")
                    raise ValidationError(msg, code='deleting_protected', params=params)
        def is_valid(self):
            result = super(DeleteProtectedModelForm, self).is_valid()
            self.hand_clean_DELETE()
            return result
    defaults['form'] = DeleteProtectedModelForm
    if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
        defaults['fields'] = forms.ALL_FIELDS
    return inlineformset_factory(self.parent_model, self.model, **defaults)

def get_max_num(

self, request, obj=None, **kwargs)

Hook for customizing the max number of extra inline forms.

def get_max_num(self, request, obj=None, **kwargs):
    """Hook for customizing the max number of extra inline forms."""
    return self.max_num

def get_ordering(

self, request)

Hook for specifying field ordering.

def get_ordering(self, request):
    """
    Hook for specifying field ordering.
    """
    return self.ordering or ()  # otherwise we might try to *None, which is bad ;)

def get_prepopulated_fields(

self, request, obj=None)

Hook for specifying custom prepopulated fields.

def get_prepopulated_fields(self, request, obj=None):
    """
    Hook for specifying custom prepopulated fields.
    """
    return self.prepopulated_fields

def get_queryset(

self, request)

def get_queryset(self, request):
    queryset = super(InlineModelAdmin, self).get_queryset(request)
    if not self.has_change_permission(request):
        queryset = queryset.none()
    return queryset

def get_readonly_fields(

self, request, obj=None)

Hook for specifying custom readonly fields.

def get_readonly_fields(self, request, obj=None):
    """
    Hook for specifying custom readonly fields.
    """
    return self.readonly_fields

def has_add_permission(

self, request)

def has_add_permission(self, request):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request)
    return super(InlineModelAdmin, self).has_add_permission(request)

def has_change_permission(

self, request, obj=None)

def has_change_permission(self, request, obj=None):
    opts = self.opts
    if opts.auto_created:
        # The model was auto-created as intermediary for a
        # ManyToMany-relationship, find the target model
        for field in opts.fields:
            if field.rel and field.rel.to != self.parent_model:
                opts = field.rel.to._meta
                break
    codename = get_permission_codename('change', opts)
    return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_delete_permission(

self, request, obj=None)

def has_delete_permission(self, request, obj=None):
    if self.opts.auto_created:
        # We're checking the rights to an auto-created intermediate model,
        # which doesn't have its own individual permissions. The user needs
        # to have the change permission for the related model in order to
        # be able to do anything with the intermediate model.
        return self.has_change_permission(request, obj)
    return super(InlineModelAdmin, self).has_delete_permission(request, obj)

def lookup_allowed(

self, lookup, value)

def lookup_allowed(self, lookup, value):
    model = self.model
    # Check FKey lookups that are allowed, so that popups produced by
    # ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
    # are allowed to work.
    for l in model._meta.related_fkey_lookups:
        for k, v in widgets.url_params_from_lookup_dict(l).items():
            if k == lookup and v == value:
                return True
    parts = lookup.split(LOOKUP_SEP)
    # Last term in lookup is a query term (__exact, __startswith etc)
    # This term can be ignored.
    if len(parts) > 1 and parts[-1] in QUERY_TERMS:
        parts.pop()
    # Special case -- foo__id__exact and foo__id queries are implied
    # if foo has been specifically included in the lookup list; so
    # drop __id if it is the last part. However, first we need to find
    # the pk attribute name.
    rel_name = None
    for part in parts[:-1]:
        try:
            field, _, _, _ = model._meta.get_field_by_name(part)
        except FieldDoesNotExist:
            # Lookups on non-existent fields are ok, since they're ignored
            # later.
            return True
        if hasattr(field, 'rel'):
            if field.rel is None:
                # This property or relation doesn't exist, but it's allowed
                # since it's ignored in ChangeList.get_filters().
                return True
            model = field.rel.to
            rel_name = field.rel.get_related_field().name
        elif isinstance(field, RelatedObject):
            model = field.model
            rel_name = model._meta.pk.name
        else:
            rel_name = None
    if rel_name and len(parts) > 1 and parts[-1] == rel_name:
        parts.pop()
    if len(parts) == 1:
        return True
    clean_lookup = LOOKUP_SEP.join(parts)
    return clean_lookup in self.list_filter or clean_lookup == self.date_hierarchy

def queryset(

*args, **kwargs)

def wrapped(*args, **kwargs):
    warnings.warn(
        "`%s.%s` is deprecated, use `%s` instead." %
        (self.class_name, self.old_method_name, self.new_method_name),
        self.deprecation_warning, 2)
    return f(*args, **kwargs)

def to_field_allowed(

self, request, to_field)

Returns True if the model associated with this admin should be allowed to be referenced by the specified field.

def to_field_allowed(self, request, to_field):
    """
    Returns True if the model associated with this admin should be
    allowed to be referenced by the specified field.
    """
    opts = self.model._meta
    try:
        field = opts.get_field(to_field)
    except FieldDoesNotExist:
        return False
    # Always allow referencing the primary key since it's already possible
    # to get this information from the change view URL.
    if field.primary_key:
        return True
    # Make sure at least one of the models registered for this site
    # references this field through a FK or a M2M relationship.
    registered_models = set()
    for model, admin in self.admin_site._registry.items():
        registered_models.add(model)
        for inline in admin.inlines:
            registered_models.add(inline.model)
    for related_object in opts.get_all_related_objects(include_hidden=True):
        related_model = related_object.model
        if (any(issubclass(model, related_model) for model in registered_models) and
                related_object.field.rel.get_related_field() == field):
            return True
    return False

def validate(

cls, model)

@classmethod
def validate(cls, model):
    validator = cls.validator_class()
    validator.validate(cls, model)