Django-CRM項目學習(一)-admin組件

開始今日份整理git

1.admin組件使用

1.1 建立django項目以及開啓APP01

sql

1.2 建立類

使用django自帶的sqlite3的小型文件型的數據庫數據庫

注:使用sqlite3類型的數據庫須要下載驅動django

在app01.models建立類瀏覽器

from django.db import models

# Create your models here.

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey('Publish', on_delete=models.CASCADE, null=True)
    # modeles.CASCADE設置串行,因爲和出版社關聯,在刪除出版社的只會刪除外鍵,不會刪除對象,只有在null
    # 爲True才能夠刪除。
    staes = models.IntegerField(choices=[(1,'已出版'),(2,'未出版')],default=1)
    author = models.ManyToManyField('Author')

    # 一對多關係

    def __str__(self):
        return self.title

class Publish(models.Model):
    # 出版社類
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Author(models.Model):
    # 做者類
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    au_detail = models.OneToOneField('Author_detail',on_delete=models.CASCADE,null=True)

    def __str__(self):
        return self.name

class Author_detail(models.Model):
    # 做者詳情類
    tel = models.CharField(max_length=32)
    address = models.CharField(max_length=64)

使用manage.py文件建立數據表並寫入到數據庫中,同時建立超級用戶網絡

makemigrations:將庫寫入到內存中
migrate:將內存中的數據寫入到數據庫中

createsuperuser:建立超級用戶,用於登錄admin頁面

1.3 admin.py文件編輯

從app01.models中引入項目各個類app

image

在下面輸入要建立的頁面ide

admin.site.register(Book,BookConfig)
admin.site.register(Publish,PublishConfig)
admin.site.register(Author,AuthorConfig)
admin.site.register(Author_detail)

啓動項目,在網頁中打開,展現以下函數

image

輸入用戶名密碼,進入到展現頁面url

image

1.4 默認顯示

對於admin註冊的默認顯示內容以下,讀取querset,若是有__str__屬性,則顯示__str__屬性。

image

1.5 自定義列表

根據上圖,對數據頁面上分別添加出版社,做者以及書籍

1.5.1 自定義展現列表

#建立一個自定義類
class BookConfig(admin.ModelAdmin):
    #用於展現多對多關係,展現書籍做者    
    # 用於展現
    list_display = ['title','price','pub_date','publish','show_authors','staes']


#在book相關admin中添加自定義類,BookConfig爲新增
admin.site.register(Book,BookConfig)

上面的list_display爲內置用法,用於顯示,最後展現以下

image

1.5.2 自定義展現多對多關係

書籍與做者的關係是多對多關係,須要自定義函數,用於展現!

#用於展現多對多關係,自定義函數show_authors,完整代碼以下
class BookConfig(admin.ModelAdmin):
    def show_authors(self,obj):
        print("obj",obj)
        return '|'.join([obj.name for obj in obj.author.all()])

    # 用於展現
    list_display = ['title','price','pub_date','publish','show_authors',]

image

多個做者用‘|’分隔。

1.5.3 反射字段

對於表中使用choices的屬相,反射對應的字段

在models中以下設置

image

image

注:

  • django如今默認會將choice的對應的值轉換對應的值,默認會顯示爲對應的出版社或者未出版社
  • obj.get_states_display()用於反射choiice對應的值

image

1.6 批量操做

批量操做爲action操做

在上面的BookConfig中寫入

#action操做
    # 價格初始化
    def patch_init(self,request,queryset):
        print('queryset',queryset)
        queryset.update(price=0)
    patch_init.short_description = '價格初始化'#設置多選服務
    # 出版狀態初始化
    def states_status(self,request,queryset):
        queryset.update(staes=2)
    states_status.short_description ='出版狀態初始化'
    # 多選服務
    actions = [patch_init,states_status]


#其中.short_description以及actions爲內置應用

展現以下

image

1.7 多重過濾

在上面的BookConfig類中寫入

#多重過濾
    list_filter = ['publish','author']

#對出版社以及做者作過濾

展現以下

image

1.8 排序

在上面的BookConfig類中寫入

# 排序
    ordering = ['price','-id']

#能夠用倆個參數進行排序,默認是升序,加-號變爲逆反

1.9 模糊查詢

# 模糊查詢
    search_fields = ['title','price']

#若是title以及價格中都有特定的參數那麼都顯示

展現以下

image

admin總體代碼

from django.contrib import admin

# Register your models here.

from app01.models import Book,Publish,Author,Author_detail

class BookConfig(admin.ModelAdmin):
    def show_authors(self,obj):
        print("obj",obj)
        return '|'.join([obj.name for obj in obj.author.all()])

    # 用於展現
    list_display = ['title','price','pub_date','publish','show_authors','staes']
    # 用於設置鏈接的內容
    list_display_links = ['title','price']

    #action操做
    # 價格初始化
    def patch_init(self,request,queryset):
        print('queryset',queryset)
        queryset.update(price=0)
    patch_init.short_description = '價格初始化'#設置多選服務
    # 出版狀態初始化
    def states_status(self,request,queryset):
        queryset.update(staes=2)
    states_status.short_description ='出版狀態初始化'
    # 多選服務
    actions = [patch_init,states_status]


    #多重過濾
    list_filter = ['publish','author']

    # 排序
    ordering = ['price','-id']

    # 模糊查詢
    search_fields = ['title','price']


class PublishConfig(admin.ModelAdmin):
    list_display = ['name','city','email']


class AuthorConfig(admin.ModelAdmin):
    def show_tel(self,obj):
        print('obj',obj)
        return obj.au_detail.tel
    def show_address(self,obj):
        print('obj',obj)
        return obj.au_detail.address
    list_display = ['name','age','show_tel','show_address']

admin.site.register(Book,BookConfig)
admin.site.register(Publish,PublishConfig)
admin.site.register(Author,AuthorConfig)
admin.site.register(Author_detail)
admin總體代碼

1.10 其餘操做

1.10.1 list_display,列表時,定製顯示的列。

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

1.10.2 list_display_links,列表時,定製列能夠點擊跳轉。

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

1.10.3  list_filter,列表時,定製右側快速篩選。

1.10.4 list_select_related,列表時,連表查詢是否自動select_related

1.10.5 list_editable,列表時,能夠編輯的列

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

1.10.6 search_fields,列表時,模糊搜索的功能

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

1.10.7 date_hierarchy,列表時,對Date和DateTime類型進行搜索

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

1.10.8 inlines,詳細頁面,若是有其餘表和當前表作FK,那麼詳細頁面能夠進行動態增長和刪除

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

1.10.9 action,列表時,定製action中的操做

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
 
    # 定製Action行爲具體方法
    def func(self, request, queryset):
        print(self, request, queryset)
        print(request.POST.getlist('_selected_action'))
 
    func.short_description = "中文顯示自定義Actions"
    actions = [func, ]
 
    # Action選項都是在頁面上方顯示
    actions_on_top = True
    # Action選項都是在頁面下方顯示
    actions_on_bottom = False
 
    # 是否顯示選擇個數
    actions_selection_counter = True

1.10.10 定製HTML模板

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

1.10.11 raw_id_fields,詳細頁面,針對FK和M2M字段變成以Input框形式

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

1.10.12 fields,詳細頁面時,顯示字段的字段

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

1.10.13 exclude,詳細頁面時,排除的字段

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

1.10.14 readonly_fields,詳細頁面時,只讀字段

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

1.10.15 fieldsets,詳細頁面時,使用fieldsets標籤對數據進行分割顯示

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    fieldsets = (
        ('基本數據', {
            'fields': ('user', 'pwd', 'ctime',)
        }),
        ('其餘', {
            'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'
            'fields': ('user', 'pwd'),
        }),
    )

1.10.16 詳細頁面時,M2M顯示時,數據移動選擇(方向:上下和左右)

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)

1.10.17 ordering,列表時,數據排序規則

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

1.10.18 radio_fields,詳細頁面時,使用radio顯示選項(FK默認使用select)

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

1.10.19 form = ModelForm,用於定製用戶請求時候表單驗證

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

1.10.20 empty_value_display = "列數據爲空時,顯示默認值"

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    empty_value_display = "列數據爲空時,默認顯示"
 
    list_display = ('user','pwd','up')
 
    def up(self,obj):
        return obj.user
    up.empty_value_display = "指定列數據爲空時,默認顯示"

2. admin 源碼解析

對於admin組件的使用,在初期主要是有四大關鍵點,按照這幾個點開解析源碼

  • admin組件的啓動
  • 模塊的註冊
  • URLS的設計
  • URLS的增刪改查

2.1 admin的啓動

(1)django在啓動項目的時候,首先會讀取settings文件,讀取配置文件,執行settings中的INSTALLED_APPS

,咱們能夠看到第一個就是django.contrib.admin

image

(2)查看admin文件

from django.contrib import admin

image

注:

  • 引入一個模塊,除了函數,其餘都會被執行一遍
  • __all__,導入就會執行裏面的函數

(3)admin.py文件的執行順序

執行順序是按照app的註冊順序來執行

image

2.2 admin的註冊

2.2.1 面向對象的補充

單例模式,經常使用方式主要有__new__方式以及基於模塊的單例模式

#1.基於__new__方式的單例模式
class Animal(object):
    __instance =None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance
    
    
#2.基於模塊的單例模式
class Dog():
    def __init__(self):
        pass
    
    def run(self):
        print('is running......')

dog1 = Dog()
# 其餘人引用這個模塊中dog1就是一個永遠單獨的例子

補充:

  1. 單例的好處:減小實例化對象佔用的空間,加快整個程序的運行速度
  2. 實例化的對象,只是保留類的類指針,並不保留類方法
  3. 變量的查詢順序:實例對象的名稱空間~類名稱空間~父類的名稱空間
  4. 一個項目只會有一個程序,實例化對象都在一個名稱空間,對於基於模塊的單例模式,無論怎麼引用,都是指向的一個。

2.2.2 admin的site

查看site源碼

from django.contrib import admin

from django.contrib.admin.sites import AdminSite, site

#最後進入site源碼

image

2.2.3 site的register方法

查看site的AdminSite類,查看裏面的register方法

image

對於register方法來講最重要的就是上面紅框內的倆句話,分別解析

2.2.3.1 第一句

image

下面在看下admin的默認樣式

image

2.2.3.2 第二句

第二句的前提

image

site在實例化開始的時候就定義了一個空的字典,用於存放每一個app註冊的表以及他的樣式。

image

在app01中stark中註冊book以及publish,展現以下

{<class 'app01.models.Publish'>: <stark.services.sites.ModelStark object at 0x03B86BF0>, 
<class 'app01.models.Book'>: <app01.stark.BookConfig object at 0x03B86B90>}

####展現字典中的內容####

2.3 URLS的設計以及URLS的增刪改查(超重點)

其實就是解析path('admin/', admin.site.urls),這句話

2.3.1 補充知識點

APPEND_SLASH = True #默認爲True

這個參數的主要做用爲補全網絡的’/’這個符號,若是沒有django會補全,並讓瀏覽器從新發送請求

image

2.3.2 URL分發

以前在使用django的時候,是使用include方法作內容分發到不一樣的app中

#普通的二級分發
path("test",([
    path("abc",test01),
    path("bcd",test02),
],None,None))


#普通的三級分發
path("test",([
    path("abc",([
        path('123',test03),
        path('456',test04),
                ],None,None)),
    path("bcd",test02)
],None,None))

2.3.3 自定義admin的url分發

解析自定義admin的url分發功能

def get_urls2():
    # 用於生成三級分發目錄,增刪改查
    temp=[
        path("",list_view),
        path("add/",add_view),
        path("(\d+)/change/",change_view),
        path("(\d+)/delete/",delete_view),
    ]
    return (temp,None,None)

def get_url():
    #動態的爲註冊的模型類建立增刪改查的URL
    temp=[]
    #admin.site._registry爲註冊模型類時生成的那個字典
    for model,config_obj in admin.site._registry.items():
        # 獲取數據庫中每張數據表的表名字段
        model_name = model._meta.model_name
        #獲取對應項目的項目名稱,例如app01
        app_label = model._meta.app_label


        temp.append(
            path("%s/%s/" % (app_label, model_name), get_urls2())
        )
    return (temp, None, None)

urlpatterns = [
    path('admin/', admin.site.urls),
    path("stark/",get_urls())#後面用於獲取urls
]

這樣就建立好了一個admin的增刪改查的分發功能,其中有幾個側重點

admin.site._registry爲註冊模型類時生成的那個字典

# 獲取數據庫中每張數據表的表名字段
model_name = model._meta.model_name
#獲取對應項目的項目名稱,例如app01
app_label = model._meta.app_label

a

相關文章
相關標籤/搜索