多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 1. 首先建立Django项目 > Django是一款python的web开发框架 > 与MVC有所不同,属于MVT框架 > m表示model,负责与数据库交互 > v表示view,是核心,负责接收请求、获取数据、返回结果 > t表示template,负责呈现内容到浏览器 * 数据库是Django默认的sqlite3数据库 1. 建立项目 > 1. pycharm > 【file】>【new project】>【Django】 > 2. 或者执行命令: >django-admin startproject test1 项目目录如下 ![](https://box.kancloud.cn/d5bda5704f68b68bba09ef92a749e3f5_185x205.png) > 1. settings.py : > web项目中的整体配置 > 2. urls: > 通过正则匹配请求URL > 3. manage.py: > 一个命令行工具,可以使你用多种方式对Django项目进行交互 > 4. wsgi.py: > 项目与WSGI兼容的Web服务器入口 ## 2. 创建一个应用 ### 2.1 创建应用 #### 1. 直接用pycharm的命令行即可(直接在项目目录下) ![](https://box.kancloud.cn/7e90ddae5de92be5a61c4a8a52ae0a04_462x74.png) #### 2. 执行建立应用命令 ~~~ python manage.py startapp booktest ~~~ 这时会在Django项目下出现我们刚才建立的应用 ![](https://box.kancloud.cn/f4979440047b8509c931963721cbb22a_212x299.png) 其中templates目录是后边自己建立的,用于web展示的HTML模板 #### 3. 注册应用 激活模型:编辑settings.py文件,将booktest应用加入到installed_apps中,否则在数据库迁移时,模型类不会起作用 ~~~ INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'booktest' # 新建的应用 ] ~~~ ### 2.2 models(数据库交互) > Django是一个MVT框架,model是数据库交互部分 #### 2.2.1 创建与数据库映射的对象 > * 有一个数据表,就有一个模型类与之对应 > * 打开models.py文件,定义模型类 > * 引入包from django.db import models > * 模型类继承自models.Model类 > * 说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长 > * 当输出对象时,会调用对象的str方法 1. 在新创建的应用booktest中的models.py文件中,创建映射对象 ~~~ from django.db import models class BookInfo(models.Model): btitle = models.CharField(max_length=20) bpub_date = models.DateField() # 加方法不影响数据库的映射 def __str__(self): return self.btitle class HeroInfo(models.Model): hname = models.CharField(max_length=10) hgender = models.BooleanField() hcontent= models.CharField(max_length=1000) hbook = models.ForeignKey(BookInfo) # 外键映射 def __str__(self): return self.hname ~~~ 2. 生成迁移文件:根据模型类生成sql语句 ~~~ python manage.py makemigrations ~~~ > 迁移文件被生成到应用的migrations目录 ![](https://box.kancloud.cn/3d523f0f796634650266400354ac81b4_223x112.png) 3. 执行迁移:执行sql语句生成数据表 ~~~ python manage.py migrate ~~~ ![](https://box.kancloud.cn/b64151d36538deade3dbf4af5ab4f8d2_342x409.png) > 此时,根据我们定义的模型类,在数据库生成了相应的两张空表 * 此时可以用命令行的方式向数据库插入数据 `python manage.py shell` 进入命令行 导包 ~~~ from booktest.models import BookInfo,HeroInfo from django.utils import timezone from datetime import * ~~~ > 1. 查询所有图书信息: `BookInfo.objects.all()` > 2. 新建图书信息: ~~~ b = BookInfo() b.btitle="射雕英雄传" b.bpub_date=datetime(year=1990,month=1,day=10) b.save() ~~~ > 3. 查找图书信息: `b=BookInfo.objects.get(pk=1)` > 4. 输出图书信息: ~~~ b b.id b.btitle ~~~ > 5. 修改图书信息: ~~~ b.btitle=u"天龙八部" b.save() ~~~ > 6. 删除图书信息: `b.delete()` > 7. 关联对象的操作 > 对于HeroInfo可以按照上面的操作方式进行添加,注意添加关联对象 ~~~ h=HeroInfo() h.htitle=u'郭靖' h.hgender=True h.hcontent=u'降龙十八掌' h.hBook=b h.save() ~~~ > 8. 获得关联集合:返回当前book对象的所有hero > b.heroinfo_set.all() > 9. 有一个HeroInfo存在,必须要有一个BookInfo对象,提供了创建关联的数据: ~~~ h=b.heroinfo_set.create(htitle=u'黄蓉',hgender=False,hcontent=u'打狗棍法') h ~~~ 4. 运行应用 ~~~ python manage.py runserver ip:port # 指定IP和端口 python manage.py runserver port # 指定端口 ~~~ 或者 pycharm直接运行 ![](https://box.kancloud.cn/58f355d6c5065bf9caf3ed4942944098_790x181.png) #### 2.2.2.2 后台管理 Django提供了对数据库数据的web管理 1. 创建一个超级用户 `python manage.py createsuperuser # 按提示输入用户名、邮箱、密码` 2. 设置中国的时区 项目的settings文件 ~~~ LANGUAGE_CODE = 'zh-Hans' # 显示汉语 TIME_ZONE = 'Asia/Shanghai' # 显示中国时区 ~~~ 3. 登录(用我们创建的用户) ![](https://box.kancloud.cn/68a7d6565a492b34e31dbbe919ff8921_1311x645.png) * 自定义管理页面 Django提供了admin.ModelAdmin类,通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式 以下是自定义管理页面的代码 ~~~ from django.contrib import admin from booktest.models import * # Register your models here. # 注册数据库模型 """ 关联添加(每插入一个book信息,附带插入三个hero信息) 1. 定义类HeroInfoInline继承admin.StackedInline model = HeroInfo 要附带插入的类 extra = 3 附带插入的数量 2. 在要插入的类BookInfoAdmin加入附带类HeroInfoInline inlines = [HeroInfoInline] """ class HeroInfoInline(admin.StackedInline): model = HeroInfo extra = 3 # 自定义管理显示字段 class BookInfoAdmin(admin.ModelAdmin): # 管理界面展示 list_display = ['pk','btitle','bpub_date'] # 字段过滤器 list_filter = ['btitle'] inlines = [HeroInfoInline] # 向管理页面注册模型类,并自定义显示样式 admin.site.register(BookInfo,BookInfoAdmin) admin.site.register(HeroInfo) ~~~ > 1. 列表页属性: > list_display:显示字段(默认只显示模型类的__str__的返回值),可以点击列头进行排序 > ~~~ list_display = ['pk', 'btitle', 'bpub_date'] ~~~ ![](https://box.kancloud.cn/fea08c9c84b083b9a1a8e58c0e379ef2_1635x193.png) > 2. list_filter:过滤字段,过滤框会出现在右侧 ![](https://box.kancloud.cn/3aec87300b58ead75a154817bfd42880_1032x498.png) ~~~ list_filter = ['btitle'] search_fields:搜索字段,搜索框会出现在上侧 search_fields = ['btitle'] ~~~ > 3. list_per_page:分页,分页框会出现在下侧 list_per_page = 10 > 4. 添加、修改页属性 ~~~ fields:属性的先后顺序 fields = ['bpub_date', 'btitle'] fieldsets:属性分组 fieldsets = [ ('basic',{'fields': ['btitle']}), ('more', {'fields': ['bpub_date']}), ] ~~~ > 5. 关联对象 对于HeroInfo模型类,有两种注册方式 方式一:与BookInfo模型类相同 方式二:关联注册 按照BookInfor的注册方式完成HeroInfo的注册 接下来实现关联注册 #### 2.2.3 数据库模型关系 > * 定义模型 > 1. 在模型(类)中定义属性,会生成表中的字段 > * django根据属性的类型确定以下信息: > 1. 当前选择的数据库支持字段的类型 > 2. 渲染管理表单时使用的默认html控件 > 3. 在管理站点最低限度的验证 > 4. django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列 > 5. 属性命名限制 > 6. 不能是python的保留关键字 > 7. 由于django的查询方式,不允许使用连续的下划线 > * 定义属性 > 定义属性时,需要字段类型 > 字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中 > 使用方式 > 导入from django.db import models > 通过models.Field创建字段类型的对象,赋值给属性 > 对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False > * 字段类型 > 1. AutoField:一个根据实际ID自动增长的IntegerField,通常不指定 > 2. 如果不指定,一个主键字段将自动添加到模型中 > 3. BooleanField:true/false 字段,此字段的默认表单控制是CheckboxInput > 4. NullBooleanField:支持null、true、false三种值 > 5. CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput > 6. TextField:大文本字段,一般超过4000使用,默认的表单控件是Textarea > 7. IntegerField:整数 > 8. DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数 > 9. DecimalField.max_digits:位数总数 > 10. DecimalField.decimal_places:小数点后的数字位数 > 11. FloatField:用Python的float实例来表示的浮点数 > 12. DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示的日期 > 13. 参数DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false > 14. 参数DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false > 15. 该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键 > 16. auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果 > 17. TimeField:使用Python的datetime.time实例表示的时间,参数同DateField > 18. DateTimeField:使用Python的datetime.datetime实例表示的日期和时间,参数同DateField > 19. FileField:一个上传文件的字段 > 20. ImageField:继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image > * 字段选项 通过字段选项,可以实现对字段的约束,在字段对象时通过关键字参数指定 > 1. null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False > 2. blank:如果为True,则该字段允许为空白,默认值是 False > 3. 对比:null是数据库范畴的概念,blank是表单验证证范畴的 > 4. db_column:字段的名称,如果未指定,则使用属性的名称 > 5. db_index:若值为 True, 则在表中会为此字段创建索引 > 6. default:默认值 > 7. primary_key:若为 True, 则该字段会成为模型的主键字段 > 8. unique:如果为 True, 这个字段在表中必须有唯一值 > * 关系 > 1. ForeignKey:一对多,将字段定义在多的端中 > 2. ManyToManyField:多对多,将字段定义在两端中 > 3. OneToOneField:一对一,将字段定义在任意一端中 > 4. 可以维护递归的关联关系,使用'self'指定,详见“自关联” > 5. 用一访问多:对象.模型类小写_set ## 3. 视图 > 在django中,视图对WEB请求进行回应 > 视图接收reqeust对象作为第一个参数,包含了请求的信息 > 视图就是一个Python函数,被定义在views.py中 1. 新应用的views.py文件 ~~~ from django.http import * from django.shortcuts import render from django.template import RequestContext,loader from .models import * # django 的视图就是函数 # 1. 配置settings模板路径 'DIRS': [os.path.join(BASE_DIR, 'templates'),os.path.join(BASE_DIR,'booktest.templates')] # 配置urls路由 # template.render()将页面渲染 def index(request): # 必须加一个参数 # template = loader.get_template("booktest/index.html") # return HttpResponse(template.render()) 这么写麻烦 book_list = BookInfo.objects.all() # 通过模型类查询到所有的数据 context = {'list':book_list} # 传给模板 return render(request,"booktest/index.html",context) # 将数据传递给模板显示 def show(request,id): books = BookInfo.objects.get(pk=id) hero_list = books.heroinfo_set.iterator() context = {'hero_list':hero_list} return render(request,'booktest/show.html',context) ~~~ * Django提供了函数Render()简化视图调用模板、构造上下文,就不用eturn HttpResponse(template.render()) 2. 配置URL路由(把请求路由到我们写的方法) URLconf 在Django中,定义URLconf包括正则表达式、视图两部分 Django使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图 注意:只匹配路径部分,即除去域名、参数后的字符串 在test1/urls.py插入booktest,使主urlconf连接到booktest.urls模块 url(r'^', include('booktest.urls')), * 在booktest中的urls.py中添加urlconf ~~~ from django.conf.urls import url from . import views urlpatterns = [ url(r'^index',views.index), # 交给views中的index方法处理 url(r'^(\d+)$',views.show) ] ~~~ * 在项目的URL路由中,添加我们应用的路由 * 这样来自客户端的请求就会路由到我们自定义的应用中去,并找到响应的处理办法 ~~~ from django.conf.urls import url from django.contrib import admin from django.conf.urls import include urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^',include('booktest.urls')) # 把根请求后边没有东西的请求发送给booktest.urls路由 ] ~~~ ### 路径 ![](https://box.kancloud.cn/9b5727b2a2fd27e37005d002141127c1_572x296.png) ## 4. HTML模板 可以接受views中处理请求的方法传过来的值 > 1. 模板是html页面,可以根据视图中传递的数据填充值(手动创建) > 创建模板的目录如下图: ![](https://box.kancloud.cn/3943d1bbe200b1e091ee1dfbeab47aba_181x99.png) 2. 把定义的模板路径,加入到项目当中去 修改settings.py文件,设置TEMPLATES的DIRS值 ~~~ 'DIRS': [os.path.join(BASE_DIR, 'templates'),os.path.join(BASE_DIR,'booktest.templates')] ~~~ 以下是两个简单的模板 index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <ul> {#执行python代码,但是与python不同的是有for有结束#} {% for book in list%} <li> <a href="{{book.id}}">{{ book.btitle}}</a></li> {%endfor%} </ul> </body> </html> ~~~ {{book.id}} 取值,固定写法 {% for 。。 %} 插入python代码 show.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>show heroes</title> </head> <body> <ul> {%for hero in hero_list%} <li><h3>{{ hero.hname }}</h3></li> 简介:{{ hero.hcontent }} {%endfor%} </ul> </body> </html> ~~~