我的python之路【第十四章】Django站点管理(Admin)

1.3 管理站点:

1.3.1 启动服务器

  • 运行如下命令可以开启服务器

      python manage.py runserver ip:port
    
  • 可以不写ip,默认端口为8000

  • 这是一个纯python编写的轻量级web服务器,仅在开发阶段使用

  • 服务器成功启动后,提示如下信息:

      (MyTest) [root@docker-1 test1]# python manage.py runserver
      Performing system checks...
    
      System check identified no issues (0 silenced).
      May 16, 2018 - 07:55:07
      Django version 1.8.2, using settings 'test1.settings'
      Starting development server at http://127.0.0.1:8000/
      Quit the server with CONTROL-C.
    
  • 默认端口是8000,可以修改端口

      python manage.py runserver 8080
    
  • 打开浏览器,输入网址“127.0.0.1:8000”可以打开默认页面

  • 如果修改文件不需要重启服务器,如果增删文件需要重启服务器

  • 通过ctrl+c停止服务器

1.3.2 管理操作(admin)

  • 站点分为“内容发布”和“公共访问”两部分
  • “内容发布”的部分负责添加、修改、删除内容,开发这些重复的功能是一件单调乏味、缺乏创造力的工作。为此,Django会根据定义的模型类完全自动地生成管理模块
1) 使用django的管理
  • 创建一个管理员用户

      python manage.py createsuperuser,按提示输入用户名、邮箱、密码
    
  • 启动服务器,通过“127.0.0.1:8000/admin”访问,输入上面创建的用户名、密码完成登录

  • 进入管理站点,默认可以对groups、users进行管理

2) 管理界面本地化
  • 编辑settings.py文件,设置编码、时区

    LANGUAGE_CODE = 'zh-Hans'
    TIME_ZONE = 'Asia/Shanghai'

5) 向admin注册booktest的模型
	from django.contrib import admin
	from models import BookInfo
	admin.site.register(BookInfo)
  • 刷新管理页面,可以对BookInfo的数据进行增删改查操作
  • 问题:如果在str方法中返回中文,在修改和添加时会报ascii的错误
  • 解决:在str()方法中,将字符串末尾添加“.encode('utf-8')”
6) 自定义管理页面
  • Django提供了admin.ModelAdmin类

  • 通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式

      class QuestionAdmin(admin.ModelAdmin):
          ...
      admin.site.register(Question, QuestionAdmin)
    
列表页属性
  • list_display:显示字段,可以点击列头进行排序

      list_display = ['pk', 'btitle', 'bpub_date']
    
  • list_filter:过滤字段,过滤框会出现在右侧

      list_filter = ['btitle']
    
  • search_fields:搜索字段,搜索框会出现在上侧

     search_fields = ['btitle']
    
  • list_per_page:分页,分页框会出现在下侧

      list_per_page = 10
    
添加、修改页属性
  • fields:属性的先后顺序

      fields = ['bpub_date', 'btitle']
    
  • fieldsets:属性分组

      fieldsets = [
          ('basic',{'fields': ['btitle']}),
          ('more', {'fields': ['bpub_date']}),
      ]
    
7) 关联对象
  • 对于HeroInfo模型类,有两种注册方式

    • 方式一:与BookInfo模型类相同
    • 方式二:关联注册
  • 按照BookInfor的注册方式完成HeroInfo的注册

  • 接下来实现关联注册

      from django.contrib import admin
      from models import BookInfo,HeroInfo
    
      class HeroInfoInline(admin.StackedInline):
          model = HeroInfo
          extra = 2
    
      class BookInfoAdmin(admin.ModelAdmin):
          inlines = [HeroInfoInline]
    
      admin.site.register(BookInfo, BookInfoAdmin)
    
    
      备注:
      		会在BookInfo管理页面中出现HeroInfo的信息
      		model 指定表:admin.StackedInline 
      		extra 显示几条信息
    
  • 可以将内嵌的方式改为表格(比上面分布合理)

      class HeroInfoInline(admin.TabularInline)
    
8) 布尔值的显示
  • 发布性别的显示不是一个直观的结果,可以使用方法进行封装

      def gender(self):
          if self.hgender:
              return '男'
          else:
              return '女'
      gender.short_description = '性别'
    
  • 在admin注册中使用gender代替hgender

      class HeroInfoAdmin(admin.ModelAdmin):
          list_display = ['id', 'hname', 'gender', 'hcontent']
    

1.4 视图

  • 在django中,视图对WEB请求进行回应

  • 视图接收reqeust对象作为第一个参数,包含了请求的信息

  • 视图就是一个Python函数,被定义在views.

      #coding:utf-8
      from django.http import HttpResponse
    
      def index(request):
          return HttpResponse("index")
      def detail(request,id):
          return HttpResponse("detail %s" % id)
    
  • 定义完成视图后,需要配置urlconf,否则无法处理请求

1.4.1 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'^$', views.index),
          url(r'^([0-9]+)/$', views.detail),
      ]
    

1.5 模板

  • 模板是html页面,可以根据视图中传递的数据填充值

  • 创建模板的目录如下图:

      ├── manage.py
      ├── templates
      │   └── booktest
      └── test1
    
  • 修改settings.py文件,设置TEMPLATES的DIRS值

      'DIRS': [os.path.join(BASE_DIR, 'templates')],
    
  • 在模板中访问视图传递的数据

      {{输出值,可以是变量,也可以是对象.属性}}
      {%执行代码段%}
    
1.5.1 定义index.html模板
	<!DOCTYPE html>
	<html>
	<head>
	  <title>首页</title>
	</head>
	<body>
	<h1>图书列表</h1>
	<ul>
	{%for book in booklist%}
	<li>
	  <a href="{{book.id}}">
	    {{book.btitle}}
	  </a>
	</li>
	{%endfor%}
	</ul>
	</body>
	</html>
1.5.2 定义detail.html模板
  • 在模板中访问对象成员时,都以属性的方式访问,即方法也不能加括号

      <!DOCTYPE html>
      <html>
      <head>
        <title>详细页</title>
      </head>
      <body>
      <h1>{{book.btitle}}</h1>
      <ul>
        {%for hero in book.heroinfo_set.all%}
        <li>{{hero.hname}}---{{hero.hcontent}}</li>
        {%endfor%}
      </ul>
      </body>
      </html>
    
1.5.3 使用模板
  • 编辑views.py文件,在方法中调用模板 (此方法没成功-用于理解学习模板渲染过程)

      from django.http import HttpResponse
      from django.template import RequestContext, loader
      from models import BookInfo
    
      def index(request):
          booklist = BookInfo.objects.all()
          template = loader.get_template('booktest/index.html')
          context = RequestContext(request, {'booklist': booklist})
          return HttpResponse(template.render(context))
    
    
      def detail(reqeust, id):
          book = BookInfo.objects.get(pk=id)
          template = loader.get_template('booktest/detail.html')
          context = RequestContext(reqeust, {'book': book})
          return HttpResponse(template.render(context))
    
1.5.4 去除模板的硬编码
  • 在index.html模板中,超链接是硬编码的,此时的请求地址为“127.0.0.1/1/”

      <a href="{{book.id}}">
    
  • 此时的请求地址应该为“127.0.0.1/book/1/”

  • 问题总结:如果在模板中地址硬编码,将来urlconf修改后,地址将失效

  • 解决:使用命名的url设置超链接

  • 修改test1/urls.py文件,在include中设置namespace

      url(r'^', include('booktest.urls', namespace='booktest')),
    
  • 修改booktest/urls.py文件,设置name

      url(r'^book/([0-9]+)/$', views.detail, name="detail"),
    
  • 修改index.html模板中的链接

      <a href="{%url 'booktest:detail' book.id%}">
    
1.5.5 Render简写 (常用写法)
  • Django提供了函数Render()简化视图调用模板、构造上下文

      from django.shortcuts import render
      from models import BookInfo
    
      def index(reqeust):
          booklist = BookInfo.objects.all()
          return render(reqeust, 'booktest/index.html', {'booklist': booklist})
    
    
      def detail(reqeust, id):
          book = BookInfo.objects.get(pk=id)
          return render(reqeust, 'booktest/detail.html', {'book': book})
    
posted @ 2018-08-23 17:08  saynobody  阅读(93)  评论(0编辑  收藏  举报