1.8.2 版本是一个稳定性高、使用广、文档多的版本:
pip.exe install django==1.8.2
进入 python shell,查看版本:
>>> import django >>> django.get_version() ‘1.8.2‘
执行如下命令:自定义项目名称并创建基本的工程目录
E:\>django-admin startproject DjangoDemo
本示例完成“图书-英雄”两种信息的维护。“图书”、“英雄”的关系为一对多。
“图书”表结构设计:
“英雄”表结构设计:
在一个项目中可以创建一到多个应用,一个应用专门处理一种业务。
在项目根目录下,执行创建应用的命令:
python manage.py startapp hero_book
应用的目录结构如下图:
步骤如下:
1 from django.db import models 2 3 # 声明表名 4 class BookInfo(models.Model): 5 # 声明表字段 6 book_title = models.CharField(max_length=20) # 字符串类型且限定数据长度 7 book_public_date = models.DateTimeField() # 时间类型 8 9 def __str__(self): 10 return "%d" % self.pk # 返回主键列的值 11 12 13 class HeroInfo(models.Model): 14 15 name = models.CharField(max_length=20) 16 gender = models.BooleanField() # 布尔类型 17 content = models.CharField(max_length=100) 18 Book = models.ForeignKey(‘BookInfo‘) # 主/外键关联(BookInfo 加不加引号都行) 19 20 def __str__(self): 21 return "%d" % self.pk
1)激活模型:编辑 settings.py 文件,将 hero_book 应用加入到 installed_apps 中
2)生成迁移文件:根据模型类生成 sql 语句(记录关于 models.py 的所有改动,但是还没有作用的数据库文件中)
python manage.py makemigrations
迁移文件被生成到应用的 migrations 目录:
3)执行迁移:执行 sql 语句生成数据表(将 models.py 的所有改动作用到数据库文件,更新数据库,生成数据表)
python manage.py migrate
进入 python shell,进行简单的模型 API 练习:
python manage.py shell
# 引入需要的包 >>> from booktest.models import BookInfo,HeroInfo >>> from django.utils import timezone >>> from datetime import * # 查询所有图书数据 >>> BookInfo.objects.all() [] # 新建图书数据 >>> b = BookInfo() # 映射表名 >>> b.book_title = "射雕英雄传" # 映射表字段 >>> b.book_public_date = datetime(year=1990, month=1, day=10) >>> b.save() # 查找图书数据 >>> b = BookInfo.objects.get(pk=1) # 根据主键查找 # 输出图书数据 >>> b <BookInfo: 1> >>> b.id 1 >>> b.book_title ‘射雕英雄传‘ # 修改图书数据 >>> b.book_title = "天龙八部" >>> b.save() # 删除图书数据 >>> b.delete()
>>> h = HeroInfo() >>> h.name = "郭靖" >>> h.gender = True >>> h.content = "降龙十八掌" >>> h.Book = b >>> h.save() # 获得关联集合:返回当前BookInfo对象的所有HeroInfo对象 >>> b.heroinfo_set.all() [<HeroInfo: 1>] # 有一个HeroInfo对象存在,就必须对应一个BookInfo对象 # 另一种创建关联的方式 >>> h = b.heroinfo_set.create(name="黄蓉", gender=False, content="打狗棒法") >>> h <HeroInfo: 2> >>> h.name ‘黄蓉‘
运行如下命令可以开启服务器:
python manage.py runserver ip:port
修改端口:
python manage.py runserver 8080
E:\DjangoDemo>python manage.py runserver Performing system checks... System check identified no issues (0 silenced). March 31, 2021 - 21:23:43 Django version 1.8.2, using settings ‘DjangoDemo.settings‘ Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
python manage.py createsuperuser
LANGUAGE_CODE = ‘zh-Hans‘ TIME_ZONE = ‘Asia/Shanghai‘
from django.contrib import admin from models import BookInfo admin.site.register(BookInfo) admin.site.register(HeroInfo)
1 from django.contrib import admin 2 from .models import * 3 4 5 # 自定义ModelAdmin的子类,定义BookInfo模型在站点管理界面的显示方式 6 class BookInfoAdmin(admin.ModelAdmin): 7 list_display = [‘pk‘, ‘book_title‘, ‘book_public_date‘] # list_display:显示字段,可以点击列头进行排序 8 list_filter = [‘book_title‘] # list_filter:过滤字段,过滤框会出现在右侧 9 search_fields = [‘book_title‘] # search_fields:搜索字段,搜索框会出现在上侧 10 list_per_page = 10 # list_per_page:分页,分页框会出现在下侧 11 12 13 admin.site.register(BookInfo, BookInfoAdmin) # 将ModelAdmin子类与对应的模型类放一起 14 admin.site.register(HeroInfo)
界面效果:
1 from django.contrib import admin 2 from .models import * 3 4 5 # 自定义ModelAdmin的子类,定义BookInfo模型在站点管理界面的显示方式 6 class BookInfoAdmin(admin.ModelAdmin): 7 8 ‘‘‘列表页属性‘‘‘ 9 list_display = [‘pk‘, ‘book_title‘, ‘book_public_date‘] # list_display:显示字段,可以点击列头进行排序 10 list_filter = [‘book_title‘] # list_filter:过滤字段,过滤框会出现在右侧 11 search_fields = [‘book_title‘] # search_fields:搜索字段,搜索框会出现在上侧 12 list_per_page = 10 # list_per_page:分页,分页框会出现在下侧 13 14 ‘‘‘添加、修改页属性‘‘‘ 15 # fields:属性的先后顺序 16 # fields = [‘book_public_date‘, ‘book_title‘] 17 # fieldsets:属性分组 18 fieldsets = [ 19 (‘basic‘, {‘fields‘: [‘book_title‘]}), 20 (‘more‘, {‘fields‘: [‘book_public_date‘]}), 21 ] 22 23 24 admin.site.register(BookInfo, BookInfoAdmin) # 将ModelAdmin子类与对应的模型类放一起 25 admin.site.register(HeroInfo)
页面效果:
对于 HeroInfo 模型类,有两种注册方式:
接下来实现关联注册
1 from django.contrib import admin 2 from .models import * 3 4 5 # 自定义admin.StackedInline的子类,实现关联对象的注册 6 class HeroInfoInline(admin.StackedInline): 7 model = HeroInfo 8 extra = 2 9 10 11 # 自定义ModelAdmin的子类,定义BookInfo模型在站点管理界面的显示方式 12 class BookInfoAdmin(admin.ModelAdmin): 13 14 ‘‘‘列表页的相关属性‘‘‘ 15 list_display = [‘pk‘, ‘book_title‘, ‘book_public_date‘] # list_display:显示字段,可以点击列头进行排序 16 list_filter = [‘book_title‘] # list_filter:过滤字段,过滤框会出现在右侧 17 search_fields = [‘book_title‘] # search_fields:搜索字段,搜索框会出现在上侧 18 list_per_page = 10 # list_per_page:分页,分页框会出现在下侧 19 20 ‘‘‘添加/修改页的相关属性‘‘‘ 21 # fields:属性的先后顺序 22 # fields = [‘book_public_date‘, ‘book_title‘] 23 # fieldsets:属性分组 24 fieldsets = [ 25 (‘basic‘, {‘fields‘: [‘book_title‘]}), 26 (‘more‘, {‘fields‘: [‘book_public_date‘]}), 27 ] 28 29 ‘‘‘实现关联对象的方式二‘‘‘ 30 inlines = [HeroInfoInline] 31 32 33 admin.site.register(BookInfo, BookInfoAdmin) # 将ModelAdmin子类与对应的模型类放一起 34 # admin.site.register(HeroInfo) # 实现关联对象的方式一
还可以将内嵌的方式改为表格,只需替换继承的父类:
class HeroInfoInline(admin.TabularInline)
发布性别的显示不是一个直观的结果,可以使用方法进行封装:
1 def gender(self): 2 if self.hgender: 3 return ‘男‘ 4 else: 5 return ‘女‘ 6 7 gender.short_description = ‘性别‘
在 admin 注册中使用函数名 gender 代替类属性 gender:
class HeroInfoAdmin(admin.ModelAdmin): list_display = [‘id‘, ‘name‘, ‘gender‘, ‘content‘]
1 from django.http import HttpResponse # 引入响应对象 2 3 # 定义访问主页时的响应 4 def index(request): 5 return HttpResponse("welcome index page!") 6 7 # 定义访问详情页时的响应 8 def detail(request, id): 9 return HttpResponse("detail:%s" % id)
定义完成视图后,需要配置 URLconf,否则无法处理请求。
urlpatterns = [ url(r‘^admin/‘, include(admin.site.urls)), url(r‘^‘, include(‘hero_book.urls‘)), # 关联hero_book包下的urls模块 ]
1 from django.conf.urls import url 2 from . import views 3 4 5 urlpatterns = [ 6 url(r‘^$‘, views.index), # 不带URI时 访问index函数 7 url(r‘^([0-9]+)/$‘, views.detail), # URI带数字时 访问detail函数 8 ]
模板其实就是 html 页面,可以根据视图中传递的数据填充值。
(实际上,文件扩展名并不一定要是 html。只要文件中是 html 的内容,使用其他文件扩展名也可。)
1)在根目录下创建模板的目录,如下图:
为了清晰起见,一个模板目录对应一个应用,存放该应用的所有页面。
2)修改应用的 settings.py 文件,设置 TEMPLATES 的 DIRS 值:
‘DIRS‘: [os.path.join(BASE_DIR, "DjangoDemo", "templates")], # 表示根目录下的项目目录下的templates目录
在模板中访问视图传递的数据的方式:
{{输出值,可以是变量,也可以是对象.属性}}
{%执行代码段%}
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>首页</title> 6 </head> 7 <body> 8 <h1>图书列表</h1> 9 <ul> 10 {%for book in booklist%} 11 <li> 12 <a href="book/{{book.id}}">{{book.book_title}}</a> 13 </li> 14 {%endfor%} 15 </ul> 16 </body> 17 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>详情页</title> 6 </head> 7 <body> 8 <h1>编号:{{book.id}}</h1> 9 <ul> 10 {%for hero in book.heroinfo_set.all%} 11 <li>{{hero.name}}——{{hero.content}}</li> 12 {%endfor%} 13 </ul> 14 </body> 15 </html>
编辑 views.py,在方法中调用对应的模板:
1 from django.shortcuts import render 2 from .models import BookInfo 3 4 # 首页 5 def index(request): 6 # 获取所有BookInfo对象 7 booklist = BookInfo.objects.all() 8 # render 参数2:指定模板文件;参数3:将booklist对象列表传递给模板页面中引用 9 return render(request, ‘hero_book/index.html‘, {‘booklist‘: booklist}) 10 11 # 详情页 12 def detail(request, id): 13 # 将url正则中的分组作为主键,获取对应的BookInfo对象 14 book = BookInfo.objects.get(pk=id) 15 return render(request, ‘hero_book/detail.html‘, {‘book‘: book})
原文:https://www.cnblogs.com/juno3550/p/14600823.html