代码实现:??
a.创建一个django项目,应用名app01
b.models.py文件中创建表
c.连接mysql数据库:(navicat中创建一个新的数据库)(settings.py配置文件中修改数据库连接参数)(init.py中导入pymql)
d.进行数据迁移 python manage.py makemigrations python manage.py migrate
e.admin.py中注册每一张创建的表
f.创建超级用户 makesusperuser
g.启动django文件,超级用户登录admin后台管理进行数据录入
from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32) price = models.CharField(max_length=32) publish_date = models.DateField(auto_now_add=True) # 外键字段 publish = models.ForeignKey(to=‘Publish‘,on_delete=models.CASCADE) # 多对多字段建在查询频率比较高的那张表中 authors = models.ManyToManyField(to=‘Author‘) # authors只是一个虚拟字段 # 告诉django orm自动帮你创建第三张表 # 查询的时候 可以借助该字段跨表 def __str__(self): return self.title # 必须返回一个字符串类型 否则直接报错 class Publish(models.Model): name = models.CharField(max_length=32) addr = 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.CharField(max_length=32) # 一对一字段也应该建在查询频率较高的表中 author_detail = models.OneToOneField(to=‘AuthorDetail‘,on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.CharField(max_length=32) addr = models.CharField(max_length=32) def __str__(self): return self.phone
from django.contrib import admin # Register your models here. from app01 import models class BookConfig(admin.ModelAdmin): list_display = [‘title‘, ‘price‘, ‘publish_date‘, ‘publish‘] list_display_links = [‘title‘, ‘price‘, ‘publish_date‘] search_fields = [‘title‘, ‘price‘] list_filter = [‘title‘] def patch_init(self, request, queryset): queryset.update(price=666) patch_init.short_description = ‘价格批量修改‘ actions=[patch_init] admin.site.register(models.Book,BookConfig) admin.site.register(models.Publish) admin.site.register(models.Author) admin.site.register(models.AuthorDetail)
import pymysql pymysql.install_as_MySQLdb()
DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘: ‘crm_01‘, ‘HOST‘: ‘127.0.0.1‘, ‘PORT‘: 3306, ‘USER‘:‘root‘, ‘PASSWORD‘: ‘123‘, ‘CHARSET‘: ‘utf8‘, } }
admin后台管理里面可以点击加号,删除,编辑,查看功能,实际上就是每张表的四条url
1.在应用下注册你的模型表
2.admin url的规律
http://127.0.0.1:8000/admin/app01/book/ book表的查看
http://127.0.0.1:8000/admin/app01/book/add/ book表的添加
http://127.0.0.1:8000/admin/app01/book/3/change/ book表的编辑
http://127.0.0.1:8000/admin/app01/book/3/delete/ book表的删除页面
http://127.0.0.1:8000/admin/app01/publish/ publish表的查看
http://127.0.0.1:8000/admin/app01/publish/add/ publish表的添加
http://127.0.0.1:8000/admin/app01/publish/3/change/ publish表的编辑
http://127.0.0.1:8000/admin/app01/publish/3/delete/ publish表的删除页面
ps:
1.admin会给每一个注册了的生成增删改查四条url
from django.contrib import admin from app01 import models # Register your models here. # print(‘from app01 admin‘) class BookConfig(admin.ModelAdmin): list_display = [‘title‘,‘price‘,‘publish_date‘,‘publish‘] list_display_links = [‘title‘,‘price‘] search_fields = [‘title‘,‘price‘] list_filter = [‘publish‘,‘authors‘] def patch_init(self,request,queryset): queryset.update(price=666) patch_init.short_description = ‘价格批量修改‘ actions = [patch_init] admin.site.register(models.Book,BookConfig) admin.site.register(models.Publish) admin.site.register(models.Author) admin.site.register(models.AuthorDetail) print(admin.site._registry)
admin五大参数:
admin.py中创建一个自定义类继承class BookConfig(admin.ModelAdmin):
进入admin后台管理:
点击book这张表查看数据,
list_display控制展示的字段, (admin.site.register(models.Book,BookConfig))
list_display_links:控制跳转的字段
search_fields:查询字段,是或查询,只要字段中包含单个字母或中文即可
list_filter:一般放外键字段,过滤出外键字段,并且是多个外键字段,ctrl键进行选择就是and关系查询出符合这个外键字段的book书籍显示出来
def patch_init: 自定义函数,(以下是将所有的书价格修改成666)
def patch_init(self,request,queryset):
queryset.update(price=666)
patch_init.short_description = ‘价格批量修改‘ (一切皆对象,函数也是对象, short_description就是下拉框中显示的名字)
actions = [patch_init] (actions将自定义函数放入actions中起作用)
admin 后台将所有的书打上勾,就是代表批量get_lsit获取到书籍的id找到queryset对象,然后交给patch_init函数,通过quertset的update属性进行更新
class BookConfig(admin.ModelAdmin):
list_display = [‘title‘,‘price‘,‘publish_date‘,‘publish‘]
list_display_links = [‘title‘,‘price‘]
search_fields = [‘title‘,‘price‘]
list_filter = [‘publish‘,‘authors‘]
def patch_init(self,request,queryset):
queryset.update(price=666)
patch_init.short_description = ‘价格批量修改‘
actions = [patch_init]
admin.site.register(models.Book,BookConfig)
源码:????
点击site-->site = AdminSite() --> 点击AdminSite --> 这个类中找到register方法
def register(self, model_or_iterable, admin_class=None, **options):
admin_class = admin_class or ModelAdmin
.....
admin.site.register(models.Book, BookConfig)
第一个参数self传入的就是site对象本身, 第二个参数传入的是models.Book ,第三个参数就是自定义的类,不传就用默认的ModeAdmin, 所以自定义类就要继承ModeAdmin
点击ModeAdmin 所以的默认字段, 如果没有自定义字段就采用默认字段
class ModelAdmin(BaseModelAdmin): """Encapsulate all admin options and functionality for a given model.""" list_display = (‘__str__‘,) list_display_links = () list_filter = () list_select_related = False list_per_page = 100 list_max_show_all = 200 list_editable = () search_fields = () date_hierarchy = None save_as = False save_as_continue = True save_on_top = False paginator = Paginator preserve_filters = True inlines = []
django在启动的时候会依次执行每一个应用下的admin.py文件
代码测试:
a.创建一个django项目,应用名app01
b.创建一个新的应用 startapp 02 然后在settings.py中注册app02
c. 在app01中的admin.py中print(app01) 在appo2中的admin.py中print(app02)
d.启动django项目, 打印的顺序是app01 再是app02
ps: 启动django项目,加载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‘
]
from django.contrib import admin
点击admin (加载应用下的admin.py文件)
from django.utils.module_loading import autodiscover_modules
autodiscover_modules(‘admin‘)
class ModelAdmin(BaseModelAdmin): ... # 配置类 class AdminSite(object): def __init__(self, name=‘admin‘): self._registry = {} # model_class class -> admin_class instance def register(self, model, admin_class=None, **options): """ Registers the given model(s) with the given admin class. The model(s) should be Model classes, not instances. If an admin class isn‘t given, it will use ModelAdmin (the default admin options). If keyword arguments are given -- e.g., list_display -- they‘ll be applied as options to the admin class. If a model is already registered, this will raise AlreadyRegistered. If a model is abstract, this will raise ImproperlyConfigured. """ if not admin_class: admin_class = ModelAdmin # Instantiate the admin class to save in the registry self._registry[model] = admin_class(model) site = AdminSite() admin.py注册语句 admin.site.register(models.Publish) # 仅仅是将注册了的模型表和以模型表为参数实例化产生的对象 # 当做键值对存入了site对象中的_registry字段 #请看以下打印结果的示例
admin.py
from django.contrib import admin from app01 import models # Register your models here. # print(‘from app01 admin‘) class BookConfig(admin.ModelAdmin): list_display = [‘title‘,‘price‘,‘publish_date‘,‘publish‘] list_display_links = [‘title‘,‘price‘] search_fields = [‘title‘,‘price‘] list_filter = [‘publish‘,‘authors‘] def patch_init(self,request,queryset): queryset.update(price=666) patch_init.short_description = ‘价格批量修改‘ actions = [patch_init] admin.site.register(models.Book,BookConfig) admin.site.register(models.Publish) admin.site.register(models.Author) admin.site.register(models.AuthorDetail) print(admin.site._registry)
多出的前两条是django-admin默认的两张表,而字典中的key是类名也就是可以加括号调用,并不是字符串;value是以模型表为参数产生的对象,而这个类默认是ModelAdmin, 除非自定义
,如BookConfig
""" { <class ‘django.contrib.auth.models.Group‘>: <django.contrib.auth.admin.GroupAdmin object at 0x000001A7689CE438>, <class ‘django.contrib.auth.models.User‘>: <django.contrib.auth.admin.UserAdmin object at 0x000001A768A03908>, <class ‘app01.models.Book‘>: <app01.admin.BookConfig object at 0x000001A768A03978>, <class ‘app01.models.Publish‘>: <django.contrib.admin.options.ModelAdmin object at 0x000001A768A1A400>, <class ‘app01.models.Author‘>: <django.contrib.admin.options.ModelAdmin object at 0x000001A768A1A518>, <class ‘app01.models.AuthorDetail‘>: <django.contrib.admin.options.ModelAdmin object at 0x000001A768A1A550> } """
路由分发的本质
url(r‘^test/‘,([],None,None))
路由分发源码
def get_urls(self): urlpatterns = [ url(r‘^$‘, wrap(self.index), name=‘index‘), url(r‘^login/$‘, self.login, name=‘login‘), url(r‘^logout/$‘, wrap(self.logout), name=‘logout‘), url(r‘^password_change/$‘, wrap(self.password_change, cacheable=True), name=‘password_change‘), url(r‘^password_change/done/$‘, wrap(self.password_change_done, cacheable=True), name=‘password_change_done‘), url(r‘^jsi18n/$‘, wrap(self.i18n_javascript, cacheable=True), name=‘jsi18n‘), url(r‘^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$‘, wrap(contenttype_views.shortcut), name=‘view_on_site‘), ] return urlpatterns @property def urls(self): return self.get_urls(), ‘admin‘, self.name url(r‘^admin/‘, admin.site.urls)
##admin.site.urls (点击urls,urls是装饰成属性的方法,返回的是一个元组,跟路由的本质一致,get_urls是装有多个路由的列表)
路由分发分为多个等级???
一级分发??
urls.py
from django.conf.urls import url from django.contrib import admin from django.conf import settings from django.shortcuts import HttpResponse def test1(request): return HttpResponse(‘test1‘) def test2(request): return HttpResponse(‘test2‘) urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘,([ url(r‘^test1/‘,test1), url(r‘^test2/‘,test2), ],None,None)) ]
二级路由分发?
urls.py
from django.conf.urls import url from django.contrib import admin from django.conf import settings from django.shortcuts import HttpResponse def test1(request): return HttpResponse(‘test1‘) def test2(request): return HttpResponse(‘test2‘) def test3(request): return HttpResponse(‘test3‘) def test4(request): return HttpResponse(‘test4‘) def test5(request): return HttpResponse(‘test5‘) def test6(request): return HttpResponse(‘test6‘) urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘,([ url(r‘^test1/‘,([ url(r‘^test1_1/‘,test3), url(r‘^test1_2/‘,test4), url(r‘^test1_3/‘,test5), url(r‘^test1_4/‘,test6), ],None,None)), url(r‘^test2/‘,test2), ],None,None)) ]
原文:https://www.cnblogs.com/huangxuanya/p/12184548.html