1. 程式人生 > >CRM手記-2 | Django

CRM手記-2 | Django

下劃線 外鍵 extends auto div one setup 一次 ##

#################################### kingadmin ######################################

# 需要做到的效果:點擊客戶庫,出現所有客戶信息,以及增刪改查|多條件過濾|搜索|排序等功能;
# 後臺添加相應數量的客戶;
# 給admin中客戶信息顯示樣式做自定制,包括過濾等;
# admin.py
    class CustomerAdmin(admin.ModelAdmin):
        list_display = [name,source,contact_type,contact,
consultant,consult_content,status,date] list_filter = [source,consultant,status,date] search_filed = [contact,consultant__name] # 這個consultant是外鍵,搜索其字段需要雙下劃線‘__name‘; # 註冊 admin.site.register(models.CustomerInfo,CustomerAdmin) # 顯示樣式大概如下: # 因為我們做的是插拔式kingadmin,所以創建獨立的app
python3 manage.py startapp kingadmin kingadmin # 需要獨立的static以及template STATICFILES_DIRS = [ os.path.join(BASE_DIR, statics), os.path.join(BASE_DIR, kingadmin/statics), ] TEMPLATES = [ ... DIRS:[ os.path.join(BASE_DIR, templates
), os.path.join(BASE_DIR, kingadmin/templates) ], ... ] # 將crm應用中靜態文件以及主模板都拷貝到kingadmin中; # 寫kingadmin的視圖以及urlconf # urls.py ... url(r^kingadmin/, include(kingadmin.urls)) # kingadmin中也創建一個urls.py ... url(r^login/, views.user_login), url(r^logout/, views.user_logout, name=logout), # 寫一個獨立的用戶登錄註銷,將項目中的拷貝過來做一些修改 from django.shortcuts import render,redirect from django.contrib.auth import authenticate,login,logout def user_login(request): error_message = ‘‘ if request.method == POST: username = request.POST.get(username) password = request.POST.get(password) user = authenticate(username=username,password=password) if user: login(request,user) return redirect(request.GET.get(next,/kingadmin/)) else: error_message = "worng username or password" return render(request, /kingadmin/login.html,{error_message:error_message}) def user_logout(request): logout(request) return redirect(/login/) # 出現了一個問題,訪問的還是項目中的login頁面; # 因為配置中的template配置是從上往下找的,從第一個找到login頁面就顯示了; # 修改kingadmin/login.html中的標題為kingadmin # 措施:在templates中新建一個文件夾存放html頁面,並修改login訪問路徑; # 登錄成功之後跳轉kingadmin下的首頁; # 在kingadmin中創建首頁; # urls.py ... url(r^$,views.app_index,name=app_index) # views.py def app_index(request): return render(request, /kingadmin/app_index.html) # app_index.html {% extends kingadmin/index.html %} {% block right_content %} The content for urself! {% endblock right_content %} # index.html # block在dashboard位置; {% block right_content %} {% endblock right_content %} # 將已經註冊的app顯示到頁面中;怎麽判斷有沒有註冊? # 拿到settings.py中的INSTALLED_APPS,先頁面中顯示; # views.py from PerfectCRM import settings def app_index(request): print(settings.INSTALLED_APPS) return render(request, /kingadmin/app_index.html) # 問題:如果將kingadmin搬到別的項目中呢?PerfectCRM就讀取不到; # 措施:動態導入;django.conf.settings動態獲取項目settings配置 # views.py from PerfectCRM import settings from django import conf def app_index(request): print(conf.settings.INSTALLED_APPS) return render(request, /kingadmin/app_index.html) # 模仿admin.py中自定制顯示的操作; # 在crm應用中添加kingadmin.py;完成註冊,自定制顯示等操作; # 首先,需要讓django能夠訪問到這個文件,拿到裏面的配置: # 方法:在視圖中,根據conf.settings中的字符串‘crm‘, # 找到這個應用下的kingadmin文件,執行裏面的代碼; # 知識點:反射; from django import conf def app_index(request): for app_name in conf.settings.INSTALLED_APPS: try: _module = __import__(%s.kingadmin%app_name) print(_module.kingadmin) except ImportError: pass return render(request, kingadmin/app_index.html) # 這樣就找到了kingadmin.py # 怎麽顯示app下的表? # 怎麽讓django識別admin類下的展示的一些配置?綁定表跟類; enabled_admins = { # 應用名:{‘表名‘:‘admin類‘, ...} crm:{customer: CustomerAdmin, role: RoleAdmin} } # 怎麽生成這樣的字典? # kingadmin.py中大致模樣: class CustomerAdmin(object): list_display = [name,source,...] list_filter = [source,consultant, ...] search_field = [contact, ...] admin.site.register(models.Customer,CustomerAdmin) # 並且在所有app中都支持這個註冊功能 # 再建一個student的應用,並註冊,寫一個測試model # models.py class Test(models.Model): name = models.CharField(max_length=32) # 再建一個kingadmin.py class TestAdmin(object): list_display=[name] admin.site.register(models.Test,TestAdmin) # 讀取每個app中的kingadmin,最終生成上面的全局字典; # 在kingadmin下新建sites.py # sites.py class AdminSite(object): def __init__(self): self.enabled_admins = {} def register(self,model_class,admin_class=None): """註冊admin表""" print(model_class,admin_class) site = AdminSite() # kingadmin.py from crm import models from kingadmin.sites import site class CustomerAdmin(object): pass site.register(models.Customer,CustomerAdmin) # 問題:執行kingadmin.py的操作應該是程序一啟動就執行, # 所以,不應該放在app_index()視圖中; # 措施:新建app_setup.py將這些操作寫入函數放置在這個文件中; # app_setup.py from django import conf def kingadmin_auto_discover(): for app_name in conf.settings.INSTALLED_APPS: try: _module = __import__(%s.kingadmin%app_name) print(_module.kingadmin) except ImportError: pass # views.py from kingadmin import app_setup app_setup.kingadmin_auto_discover() ... # 怎麽通過表名拿到app的名字? # 使用python3 manage.py shell 來做一些模塊屬性方法的查找 # 因為ipython3中無法進入django數據庫環境; >> from crm import models >> models.CustomerInfo # 怎麽通過表名拿到app的名字? >> models.CustomerInfo._meta <Options for CustomerInfo> >> dir(models.CustomerInfo._meta) # 將內容復制到txt中,搜app_label >> models.CustomerInfo._meta.app_label crm # 就拿到了應用名 # 構建全局字典時,嵌入應用名時需要判斷是否存在; # sites.py class AdminSite(object): def __init__(self): self.enabled_admins = {} def register(self,model_class,admin_class=None): """註冊admin表""" print(model_class,admin_class) app_name = model_class._meta.app_label model_name = model_class._meta.model_name # 全局字典中不存在這個應用名,就添加; if app_name not in self.enabled_admins: self.enabled_admins[app_name] = {} # 表名怎麽獲取? # >> models.CustomerInfo._meta.model_name self.enabled_admin[app_name][model_name] = admin_class # 只實例化一次 site = AdminSite() # 這樣就構造一個類似下面的字典 enabled_admins = { # 應用名:{‘表名‘:‘admin類‘, ...} crm:{customer: CustomerAdmin, role: RoleAdmin} } # 將字典數據返回前端,返回site就可以了; # views.py def app_index(request): return render(request, kingadmin/app_index.html, {site:site}) # app_index.html {% for app_name,app_tables in site.enabled_admins.items %} {{ app_name }}{{ app_tables }} {% endfor %} >> crm{customerinfo:<class...>} student{test:<class...>} # 只要將這些對象輸出到表格中;在bootstrap中找表格示例; {% for app_name,app_tables in site.enabled_admins.items %} <table class="table table-striped"> <thead> <tr> <th>{{ app_name }}</th> </tr> </thead> <tbody> {% for model_name in app_tables %} <tr> <td><a href="{% url ‘table_obj_list‘ app_name model_name %}">{{ model_name }}</a></td> <td>ADD</td> <td>Change</td> </tr> {% endfor %} </tbody> </table> # crm中多註冊幾個表 site.register(models.Role) site.register(models.Menus) site.register(models.UserProfile) ################################ 以上是註冊模型類到kingadmin的功能

CRM手記-2 | Django