1、單例模式:單個實例公用一個對象html
一、基於模塊的單例模式python
s1.py文件:git
class Foo(object): def test(self): print("123") v = Foo()
s2.py文件:web
from s1 import v as v1 print(v1,id(v1)) #<s1.Foo object at 0x0000000002221710> 35788560 from s1 import v as v2 print(v1,id(v2)) #<s1.Foo object at 0x0000000002221710> 35788560 # 兩個的內存地址是同樣的 # 文件加載的時候,第一次導入後,再次導入時不會再從新加載。
二、基於new方法的單例模式數據庫
class Singleton: def __new__(cls, *args, **kw): '''__new__是一個構造方法,self就是他構造的''' if not hasattr(cls, '_instance'): orig = super(Singleton, cls) cls._instance = orig.__new__(cls, *args, **kw) return cls._instance one = Singleton() two = Singleton() print(one,two) #他們兩個的地址同樣 # print(id(one),id(two)) one.name = 'alex' print(two.name)
2、Django-admin使用流程django
一、數據庫遷移session
models.py文件:app
from django.db import models class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() def __str__(self): return self.name class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True,verbose_name="編號") title = models.CharField( max_length=32,verbose_name="名稱") publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="價格") # 與Publish創建一對多的關係,外鍵字段創建在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表 authors=models.ManyToManyField(to='Author',) def __str__(self): return self.title #執行下面python語句生成相關表(數據遷移) # python3 manage.py makemigrations # python3 manage.py migrate
二、建立超級用戶ide
# python3 manage.py createsuperuser
三、admin.py中註冊表函數
from django.contrib import admin from app01 import models admin.site.register(models.Book) admin.site.register(models.Publish) admin.site.register(models.Author)
四、若是新建應用app02
# python3 manage.py startapp app02
settings.py文件添加內容:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', "app02.apps.App02Config", ] 而後在app02應用的models.py增長表,接着數據庫遷移,在app02應用的admin.py中對錶進行註冊
3、admin源碼分析
一、訪問url
def get_urls(): temp = [ url(r'^$'.format(app_name, cls_name), change_list), url(r'^add/$'.format(app_name, cls_name), add_view), url(r'^del/$'.format(app_name, cls_name), delete_view), url(r'^change/$'.format(app_name, cls_name), change_view) ] return temp url_list = [] for model_class, v in admin.site._registry.items(): cls_name = model_class._meta.model_name # 當前類名稱的小寫 app_name = model_class._meta.app_label # 當前app的名稱 方式一: # all_urls = url(r'^{0}/{1}/'.format(app_name,cls_name), (get_urls(),None,None,)) 方式二: all_urls = url(r'^{0}/{1}/'.format(app_name, cls_name), include(get_urls())) url_list.append(all_urls) urlpatterns = [ url(r'^admin/', admin.site.urls), # admin.site這個對象裏面有一個屬性_registry = {} # 點擊urls查看源碼返回的是一個元組,元組的第一個元素是一個列表 url(r'^index/', ( [ url(r'^app01/userinfo/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ], None, None), name="login"), url(r'^app01/usertype/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ], None, None), name="login"), ], None, None)), url(r'^app02/article/', ([ url(r'^$', change_list, name="login"), url(r'^add/$', add_view, name="login"), url(r'^(\d+)/del/$', delete_view, name="login"), url(r'^(\d+)/change/$', change_view, name="login"), ], None, None), name="login"), # index和index2的兩個是同樣的,咱們能夠用index2的方式替代index url(r'^index2/', (url_list, None, None,)), ]
二、admin源碼流程
a. 運行程序,找到每個app中的 admin.py 文件,並加載 - app01.admin.py - 建立admin.site中的對象 - 執行對象的 register方法,目的:將註冊類添加到 _registry中 _registry = { key是傳進來的model value:是ModelAdmin的對象,傳了兩個參數 models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) } - app02.admin.py - 用app01.admin中建立那個admin.site對象 - 執行對象的 register方法,目的:講註冊類添加到 _registry中 _registry = { models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) } admin.site是一個對象(單例模式建立),其中封裝了: _registry = { models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) } b. urls.py 再次調用 admin.site 對象的 urls屬性: urlpatterns = [ url(r'^admin/', admin.site.urls), ] class ModelAdmin(object): def __init__(self,model_class,site): self.model_class = model_class self.site = site def changelist_view(self,request): data_list = self.model_class.objects.all() #是動態的 return HttpResponse('列表頁面') def add_view(self,request): return HttpResponse('添加頁面') def delete_view(self,request,nid): return HttpResponse('刪除頁面') def change_view(self,request,nid): return HttpResponse('修改頁面') def get_urls(self): urlpatterns = [ url(r'^$', self.changelist_view), url(r'^add/$', self.add_view), url(r'^(.+)/delete/$', self.delete_view), url(r'^(.+)/change/$', self.change_view), ] return urlpatterns @property def urls(self): return self.get_urls() class AdminSite(object): def __init__(self): self._registry = {} def register(self,model_class,model_admin): self._registry[model_class] = model_admin(model_class,self) def get_urls(self): """ models.Role: ModelAdmin(models.Role,admin.site), models.UserInfo: ModelAdmin(models.UserInfo,admin.site) models.UserType: ModelAdmin(models.UserType,admin.site) models.Article: ModelAdmin(models.Article,admin.site) """ url_list = [] for model_class,model_admin in self._registry.items(): model_class是一個類 app_name = model_class._meta.app_label model_name = model_class._meta.model_name url_list += [ url('%s/%s' %(app_name,model_name,), include(model_admin.urls)) ] return url_list @property def urls(self): return (self.get_urls(), None,None )
4、Django-admin(web頁面顯示)
models.py文件:
from django.db import models class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # 與AuthorDetail創建一對一的關係 authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 與Publish創建一對多的關係,外鍵字段創建在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 與Author表創建多對多的關係,ManyToManyField能夠建在兩個模型中的任意一個,自動建立第三張表 authors=models.ManyToManyField(to='Author',)
admin.py文件:
from django.contrib import admin # Register your models here. from .models import * #定製功能 class BookConfig(admin.ModelAdmin): list_display = ["nid","title","price","publishDate","publish"] #顯示的列 list_display_links=["title","price"] #字段能夠點擊跳轉 list_filter=["title","publish"] #定製右側快速篩選 search_fields=["title"] #列表時,模糊搜索的功能 def patch_init(self,request,queryset): #批量操做執行的函數 queryset.update(price=100) patch_init.short_description = "批量初始化" #批量操做顯示的描述 actions = [patch_init] #對所選擇的選項執行批量操做函數 #change_list_template="list.html" #定製HTML模板 ordering=("price","nid",) #數據排序規則 admin.site.register(Book,BookConfig) #第一個參數是對哪一個表進行註冊,第二個參數是新增的自定義的功能類,這樣book頁面就會顯示新的功能了 admin.site.register(Publish) admin.site.register(Author) admin.site.register(AuthorDetail)
其餘的一些定製功能:
一、分頁
# 分頁,每頁顯示條數 list_per_page = 100 # 分頁,顯示所有(真實數據<該值時,纔會有顯示所有) list_max_show_all = 200 # 分頁插件 paginator = Paginator
二、list_editable,列表時,能夠編輯的列
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd','ug',) list_editable = ('ug',)
三、date_hierarchy,列表時,對Date和DateTime類型進行搜索
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): date_hierarchy = 'ctime'
四、preserve_filters,詳細頁面,刪除、修改,更新後跳轉回列表後,是否保留原搜索條件
五、save_as = False,詳細頁面,按鈕爲「Sava as new」 或 「Sava and add another」
save_as_continue = True # 若是 save_as=True,save_as_continue = True, 點擊Sava as new 按鈕後繼續編輯。 # 若是 save_as=True,save_as_continue = False,點擊Sava as new 按鈕後返回列表。
六、save_on_top = False,詳細頁面,在頁面上方是否也顯示保存刪除等按鈕
七、inlines,詳細頁面,若是有其餘表和當前表作FK,那麼詳細頁面能夠進行動態增長和刪除
class UserInfoInline(admin.StackedInline): # TabularInline extra = 0 model = models.UserInfo class GroupAdminMode(admin.ModelAdmin): list_display = ('id', 'title',) inlines = [UserInfoInline, ]
八、raw_id_fields,詳細頁面,針對FK和M2M字段變成以Input框形式
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)
九、fields,詳細頁面時,顯示字段的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fields = ('user',)
十、exclude,詳細頁面時,排除的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): exclude = ('user',)
十一、readonly_fields,詳細頁面時,只讀字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): readonly_fields = ('user',)
十二、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三、詳細頁面時,M2M顯示時,數據移動選擇(方向:上下和左右)
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)
1四、view_on_site,編輯時,是否在頁面上顯示view on set
view_on_site = False 或 def view_on_site(self, obj): return 'https://www.baidu.com'
1五、radio_fields,詳細頁面時,使用radio顯示選項(FK默認使用select)
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
1六、show_full_result_count = True,列表時,模糊搜索後面顯示的數據個數樣式
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): # show_full_result_count = True # 1 result (12 total) # show_full_result_count = False # 1 result (Show all) search_fields = ('user',)
1七、formfield_overrides = {},詳細頁面時,指定現實插件
from django.forms import widgets from django.utils.html import format_html class MyTextarea(widgets.Widget): def __init__(self, attrs=None): # Use slightly better defaults than HTML's 20x2 box default_attrs = {'cols': '40', 'rows': '10'} if attrs: default_attrs.update(attrs) super(MyTextarea, self).__init__(default_attrs) def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, name=name) return format_html('<textarea {}>\r\n{}</textarea>',final_attrs, value) @admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): formfield_overrides = { models.models.CharField: {'widget': MyTextarea}, }
1八、prepopulated_fields = {},添加頁面,當在某字段填入值後,自動會將值填充到指定字段。
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): prepopulated_fields = {"email": ("user","pwd",)} PS: DjangoAdmin中使用js實現功能,頁面email字段的值會在輸入:user、pwd時自動填充
1九、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
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 = "指定列數據爲空時,默認顯示"