Source code for djconfig.admin

# -*- coding: utf-8 -*-

"""
This module allows to register a config into django's admin.

Usage::

    class FooConfigAdmin(djconfig.admin.ConfigAdmin):
        change_list_form = FooConfigForm


    class FooConfig(djconfig.admin.Config):
        app_label = 'djconfig'
        verbose_name_plural = 'foo config'
        name = 'fooconfig'

    djconfig.admin.register(FooConfig, FooConfigAdmin)
"""

import re

from django.contrib import admin
from django.apps import apps
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
from django.contrib.admin.options import csrf_protect_m
from django.contrib.admin import helpers
from django.core.exceptions import PermissionDenied
from django.conf.urls import url

from .forms import ConfigForm

__all__ = [
    'ConfigAdmin',
    'Config',
    'register']


[docs]class ConfigAdmin(admin.ModelAdmin): """ A ``ConfigAdmin`` is subclass of \ ``django.contrib.admin.ModelAdmin``. ``change_list_form`` class var must be set to a valid \ ``djconfig.forms.ConfigForm`` subclass """ change_list_template = 'admin/djconfig/change_list.html' change_list_form = None def get_urls(self): info = self.model._meta.app_label, self.model._meta.module_name return [ url(r'^$', self.admin_site.admin_view(self.changelist_view), name='%s_%s_changelist' % info), url(r'^$', self.admin_site.admin_view(self.changelist_view), name='%s_%s_add' % info), ] def get_changelist_form(self, request, **kwargs): return self.change_list_form @csrf_protect_m def changelist_view(self, request, extra_context=None): if not self.has_change_permission(request, None): raise PermissionDenied form_cls = self.get_changelist_form(request) form = form_cls() if request.method == 'POST': form = form_cls(data=request.POST, files=request.FILES) if form.is_valid(): form.save() return HttpResponseRedirect('.') context = dict( self.admin_site.each_context(request), config_values=[], title=self.model._meta.verbose_name_plural, app_label=self.model._meta.app_label, opts=self.model._meta, form=form, media=self.media + form.media, icon_type='svg', adminform=helpers.AdminForm( form=form, fieldsets=[(None, {'fields': form.base_fields})], prepopulated_fields=self.get_prepopulated_fields(request)) ) request.current_app = self.admin_site.name return TemplateResponse(request, self.change_list_template, context)
class _ConfigMeta(object): app_label = '' object_name = '' model_name = module_name = '' verbose_name_plural = '' abstract = False swapped = False def get_ordered_objects(self): return False def get_change_permission(self): return 'change_djconfig_config' @property def app_config(self): return apps.get_app_config(self.app_label)
[docs]class Config(object): """ A ``Config`` is akin to django's model ``Meta`` class. ``app_label`` must be a valid installed app, ``'djconfig'`` \ may be used for every registered form, if they don't belong \ in a particular app. ``verbose_name_plural`` is the title of \ the admin's section link, it can be anything. The \ (``app_label``, ``verbose_name_plural``, ``name``) must be \ unique together across registered forms. \ ``name`` is used as the link slug, and it \ might be used in other places, valid chars are ``[a-zA-Z_]`` """ app_label = '' verbose_name_plural = '' name = ''
[docs]def register(conf, conf_admin, **options): """ Register a new admin section. :param conf: A subclass of ``djconfig.admin.Config`` :param conf_admin: A subclass of ``djconfig.admin.ConfigAdmin`` :param options: Extra options passed to ``django.contrib.admin.site.register`` """ assert issubclass(conf_admin, ConfigAdmin), ( 'conf_admin is not a ConfigAdmin subclass') assert issubclass( getattr(conf_admin, 'change_list_form', None), ConfigForm), 'No change_list_form set' assert issubclass(conf, Config), ( 'conf is not a Config subclass') assert conf.app_label, 'No app_label set' assert conf.verbose_name_plural, 'No verbose_name_plural set' assert not conf.name or re.match(r"^[a-zA-Z_]+$", conf.name), ( 'Not a valid name. Valid chars are [a-zA-Z_]') config_class = type("Config", (), {}) config_class._meta = type("Meta", (_ConfigMeta,), { 'app_label': conf.app_label, 'verbose_name_plural': conf.verbose_name_plural, 'object_name': 'Config', 'model_name': conf.name, 'module_name': conf.name}) admin.site.register([config_class], conf_admin, **options)