The use and source code analysis of Django's admin

admin component use

Django provides web-based administration tools.

The Django auto-admin tool is part of django.contrib. You can see it in INSTALLED_APPS in your project's settings.py:

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "app01"
]

  

django.contrib is a huge feature set that is part of Django's base code.

Activation Management Tool

Usually we will automatically set it in urls.py when we generate the project,

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),

]

When this is all configured, the Django admin tool is ready to run.

Use management tools

Start the development server, and then visit http://127.0.0.1:8000/admin/ in the browser to get the login interface. You can   create a superuser by running the command python manage.py createsuperuser .

In order for the admin interface to manage a data model, we need to first register the data model to the admin

from django.db import models

class Author(models.Model):

    name=models.CharField( max_length=32)
    age=models.IntegerField()

    def __str__(self):
        return self.name

class Publish(models.Model):

    name=models.CharField( max_length=32)
    email=models.EmailField()

    def __str__(self):
        return self.name


class Book(models.Model):

    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)

    publisher=models.ForeignKey(to="Publish")
    authors=models.ManyToManyField(to='Author')

    def __str__(self):
        return self.title

admin customization

In admin.py, you only need to register a class in Mode, and you can implement the function of adding, deleting, modifying and checking in Admin, such as:

admin.site.register(models.UserInfo)

However, this method is relatively simple. If you want to perform more customized operations, you need to use ModelAdmin to operate, such as:

method one:
class UserAdmin(admin.ModelAdmin):
     list_display = ('user', 'pwd',)
 
admin.site.register(models.UserInfo, UserAdmin) # The first parameter can be a list
     
 
Method two:
@admin.register(models.UserInfo) # The first parameter can be a list
class UserAdmin(admin.ModelAdmin):
    list_display = ('user', 'pwd',)

A large number of customizable features are provided in ModelAdmin, such as

 1. list_display, when listing, customize the displayed columns.

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    list_display = ('user', 'pwd', 'xxxxx')
 
    def xxxxx(self, obj):
        return "xxxxx"

2. list_display_links, in the list, the custom column can be clicked to jump.

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    list_display = ('user', 'pwd', 'xxxxx')
    list_display_links = ('pwd',)

3. list_filter, when listing, customize the quick filter on the right.

4. list_select_related, in the list, whether the query of the connected table will automatically select_related

5. list_editable, the column that can be edited when the list is 

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    list_display = ('user', 'pwd', 'ug',)
    list_editable = ('ug',)

6. search_fields, the function of fuzzy search when listing

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    search_fields = ('user', 'pwd')

  

7. date_hierarchy, when listing, searches for Date and DateTime types

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    date_hierarchy = 'ctime'

8 inlines, detailed page, if there are other tables and the current table for FK, then the detailed page can be dynamically added and deleted

class UserInfoInline(admin.StackedInline): # TabularInline
    extra = 0
    model = models.UserInfo
 
class GroupAdminMode(admin.ModelAdmin):
    list_display = ('id', 'title',)
    inlines = [UserInfoInline, ]

9 action, list, customize the action in the action

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
 
    # Customize the specific method of Action behavior
    def func(self, request, queryset):
        print(self, request, queryset)
        print(request.POST.getlist('_selected_action'))
 
    func.short_description = "Chinese display custom Actions"
    actions = [func, ]
 
    # Action options are displayed at the top of the page
    actions_on_top = True
    # Action options are displayed at the bottom of the page
    actions_on_bottom = False
 
    # Whether to display the number of choices
    actions_selection_counter = True

10 Custom HTML Templates

add_form_template = None
change_form_template = None
change_list_template = None
delete_confirmation_template = None
delete_selected_confirmation_template = None
object_history_template = None

11 raw_id_fields, detail page, for FK and M2M fields becomes in the form of Input box

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    raw_id_fields = ('FK field', 'M2M field',)

12 fields, when the detail page, the field of the field is displayed

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    fields = ('user',)

13 exclude, when the detail page, the excluded field

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    exclude = ('user',)

14 readonly_fields, detail page, read-only field

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    readonly_fields = ('user',)

15 fieldsets, when the detailed page is used, use the fieldsets tag to split the data and display

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    fieldsets = (
        ('basic data', {
            'fields': ('user', 'pwd', 'ctime',)
        }),
        ('other', {
            'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'
            'fields': ('user', 'pwd'),
        }),
    )

16 When the detail page is displayed, when M2M is displayed, the data movement selection (direction: up and down and left and right)

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    filter_vertical = ("m2m field",) # or filter_horizontal = ("m2m field",)

17 ordering, list, data sorting rules

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    ordering = ('-id',)
    or
    def get_ordering(self, request):
        return ['-id', ]

18. radio_fields, when detailed page, use radio to display options (FK uses select by default)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

19 form = ModelForm, used to customize form validation when user requests

from app01 import models
from django.forms import ModelForm
from django.forms import fields
 
class MyForm(ModelForm):
    others = fields.CharField()
 
    class Meta:
        model = models = models.UserInfo
        fields = "__all__"
 
@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
 
    form = MyForm

20 empty_value_display = "When the column data is empty, display the default value"

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    empty_value_display = "Default display when column data is empty"
 
    list_display = ('user','pwd','up')
 
    def up(self,obj):
        return obj.user
    up.empty_value_display = "When the specified column data is empty, the default display"

  

from django.contrib import admin

# Register your models here.

from .models import *




class BookInline(admin.StackedInline): # TabularInline
    extra = 0
    model = Book

class BookAdmin(admin.ModelAdmin):

    list_display = ("title",'publishDate', 'price',"foo","publisher")
    list_display_links = ('publishDate',"price")
    list_filter = ('price',)
    list_editable=("title","publisher")
    search_fields = ('title',)
    date_hierarchy = 'publishDate'
    preserve_filters=False

    def foo(self,obj):

        return obj.title+str(obj.price)



    # Customize the specific method of Action behavior
    def func(self, request, queryset):
        print(self, request, queryset)
        print(request.POST.getlist('_selected_action'))

    func.short_description = "Chinese display custom Actions"
    actions = [func, ]
    # Action options are displayed at the top of the page
    actions_on_top = True
    # Action options are displayed at the bottom of the page
    actions_on_bottom = False

    # Whether to display the number of choices
    actions_selection_counter = True



    change_list_template="my_change_list_template.html"



class PublishAdmin(admin.ModelAdmin):
     list_display = ('name', 'email',)
     inlines = [BookInline, ]



admin.site.register(Book, BookAdmin) # The first parameter can be a list
admin.site.register(Publish,PublishAdmin)
admin.site.register(Author)

admin source code analysis

singleton pattern

The Singleton Pattern is a common software design pattern whose main purpose is to ensure that only one instance of a class exists . Singleton objects come in handy when you want only one instance of a class to appear in the entire system.

For example, the configuration information of a server program is stored in a file, and the client reads the configuration file information through an AppConfig class. If the content of the configuration file needs to be used in many places during the running of the program, that is to say, instances of AppConfig objects need to be created in many places, which leads to the existence of multiple AppConfig instance objects in the system, which will seriously waste memory resources, especially if the config file has a lot of content. In fact, for a class like AppConfig, we want only one instance of the object to exist during the runtime of the program.

In Python, we can implement the singleton pattern in several ways:

  • Use modules
  • use __new__
  • Use decorators
  • Using metaclasses

(1) Use __new__

In order to make only one instance of the class appear, we can use  __new__ to control the creation process of the instance, the code is as follows:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kw):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)  
        return cls._instance  

class MyClass(Singleton):  
    a = 1

_instance In the above code, we associate  the instance of the class with a class variable  , if it cls._instance is None then create the instance, otherwise return it directly  cls._instance.

The implementation is as follows:

>>> one = MyClass()
>>> two = MyClass()
>>> one == two
True
>>> one is two
True
>>> id(one), id(two)
(4303862608, 4303862608)

(2) Using modules

In fact, Python's module is a natural singleton mode , because when the module is imported for the first time, it will generate a  .pyc file, and when it is imported for the second time, the  .pyc file will be loaded directly without executing the module code again. Therefore, we only need to define the related functions and data in a module to obtain a singleton object. If we really want a singleton class, consider doing this:

# mysingleton.py
class My_Singleton(object):
    def foo(self):
        pass
 
my_singleton = My_Singleton()

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325253880&siteId=291194637