Django创建一个项目的过程

使用Django创建一个项目

python3.6 + Django1.11


创建一个项目
django-admin startproject [mysite]此处自定义项目名字,不可是中文
生成文件目录
py@py-PC:~/text/mysite$ tree
.
├── db.sqlite3
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py

在项目中创建一个app
在manage.py 的同级目录中执行:
python3 manage.py startapp [myweb]自定义app名字,不可以是中文
生成文件目录
py@py-PC:~/text$ tree
.
└── mysite
    ├── db.sqlite3
    ├── manage.py   【启动文件】
    ├── mysite
    │   ├── __init__.py
    │   ├── settings.py   【配置文件】
    │   ├── urls.py       【主路由】
    │   └── wsgi.py
    ├── myweb			  【创建app应用的时候生成的】
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py    【创建库->表】
    │   ├── tests.py
    │   ├── urls.py      【子路由】
    │   └── views.py	 【视图】
    └── templates		 【网页文件夹,MVT模型】
        └── xx.html


创建应用的步骤
  1. 执行创建app命令【创建myweb】

  2. 在myweb/views.py中写入

    1. # render是用来返回页面的
      from django.shortcuts import render
      # HttpResponse是用来返回数据或者html标签内容的
      from django.http import HttpResponse
      def index(request,[k])return HttpResponse('')返回字符串
      	return HttpResponse('<><>')返回标签
      def xxx(request,[k])
      	return render(request,'xxx.html'k)====返回的是====/templaters/目录下面的html文件
      
  3. 修改主路由/mysite/urls.py

    1. from django.conf import url,include
      from django.contrip import admin
      
      urlpatterns = [
          # 这个url路由是主路由的admin管理员账户
          url(r'^admin/',admin.site.urls),
          # 这个主路由的正则是^什么都不限制,他包括myweb下的urls.py这个子路由,交给子路由去处理
          url(r'^',include('myweb.urls')),
      ]
      
  4. 在/myweb/目录下创建子路由urls.py

    1. # 子路由的url是引用的django.conf.url
      from django.conf.urls import url
      # 子路由处理后需要执行视图中的方法,所以要引用当前目录想的view.py这个视图
      from . import views
      urlpatterns = [
          # 匹配正字hello开头/结尾  执行views下的index方法
          url(r'^hello$/',views.index),
          # 匹配正则[0-9]数字开头匹配任意四位数子,执行views下的xxx方法
          url(r'([0-9]{4})$/',views.xxx),
      ]
      
  5. 编辑配置文件/mysite/setting.py

    1. # 编辑监听端口号为任意端口号
      ALLOWD_HOSTS = ['*']
      # 编辑templates文件路径,为根目录下的templates文件夹
      TEMPLATES = [
          ,'DIR':[os.path.join(BAST_DIR,"templates")],
      ]
      
  6. 服务请求的执行过程

用户在浏览器访问url地址的时候,django服务器接受请求----->url地址交给主路由的正则进行匹配—>交给子路由的正则匹配---->交个视图函数处理----->视图函数执行操作,返回HttpResponse或者render---->render的时候会从配置文件中查找template目录的路径

使用模板
  1. 配置模板的引擎

    1. #配置项目的配置文件/mysite/setting.py
      TEMPLATES = [
          {
              'BACKEND':'django.template.backends.django.DjangoTemplates',
              'DIRS':[os.path.join(BASE_DIR,'templates')],
              'APP_DIRS':True,
              'OPTIONS':{
                  'context_processors':[
                      'django.template.context_processors.debug',
                      'django.template.contex_processors.request',
                      'django.contrib.auth.context_processors.auth',
                      'django.contrib.messages.context_processors.messages',
                  ],
              }
          }
      ]
      
  2. 模板都放在manage.py同级目录下的templates文件夹下面

    1. 模板文件夹用来存放html页面,当render返回html页面的时候,会来这里匹配
  3. 变更访问地址的端口号

    1. 默认端口号8000 在配置文件中ALLOWED_HOSTS = [’*’]
    2. 设置监听的端口号是任意端口号
    3. 使用自定义端口号启动服务python3 manage.py runserver 0:9000
路由的匹配规则
  1. 路由安装顺序执行

  2. 路由可以使用()来捕获url请求中的一部分参数来使用

  3. 例如:

  4. 请求url路径为 http://127.0.0.1:9000/articles/2014/
    路由的规则    url(r'articles/([0-9]{4})/$',view.year_archeive),
    视图中的视图函数
    def year_archive(request,y):
        print(y)
        return HttpResponse('year_archive')
    # 注意:在有()的路由规则,那么对应的视图函数中必须给定形参,有几个()给几个形参
    # 路由参数  正则表达式命名组  在视图函数中叫关键字参数,变量名要和路由规则中定义的一致
    # 命名组的关键字是 (?P<name>正则)  其中<name>就是命名组的命名,相对应的视图函数就要使用关键字参数
    url(r'abc/(?P<year>[0-9]Z{4})/$',views.abc_2003),
    # 视图函数
    def abc_2003(request,year):
        print(year)
        return HttpResponse('abc_2003')
    
  5. 参数的默认值 两个路由规则指向同一个视图函数

  6. # 参数默认值
    url(r'^user/list/$',views.userlist),
    url(r'^user/list/(?P<page>[0-9]+)',views.userlist),
    # 视图函数
    def userlist(request,page=1):
        print(page)
        return HttpResponse('userlist')
    
  7. URL的反向解析

    1. 通过对定义的路由添加名字,动态解析路由的地址

    2. 如果在视图、模板中使用硬编码的链接,那么在urlconf发生改变时,维护特别麻烦

    3. # 动态解析url的规则,可以在定义路由规则时候,给路由起个名字
      url(r'^goods/list/$',views.goodslist,name='glist'),
      # 在模板中直接是用url标签来通过路由的名字,解析路由的地址
      <a href='{% url "glist" %}'>商品列表:反向解析格式</a>
      
    4. # 注意,路由规则中如果有参数要求,那么在使用url进行反向解析的时候,必须给定参数
      url(r'^order/list/([0-9]+)/$',views.orderlist,name='olist'),
      <a href="{% url 'olist' 100 %}" >订单列表:反向解析格式</a>
      # 在模板中反向解析{% url 'glist' %}
      # 在视图函数中使用反向解析 reverse('glist')
      
      模型

django中通过模型来控制数据库

模型是定义好的Model类,自定义的模型继承这个基础类,自定义类中定义的属性便成为了数据库表格中的字段,类名成为了表格的名字

Model提供了一套操作数据的APT,不用直接操作数据库,解耦,减少工作量,不会因更换数据库产生无效劳动

例如:

class Users(Model):
	username = models.CharField(max_length=100)
# 结果是在数据库中生成了一个名字为myweb_Users的表格
# 这个表格中会自动生成id字段【自增】以及生成username字段,类型char最大长度100
模型和数据库的关系

ORM 对象 关系 映射

任务是:

  1. 根据类,生成表结构
  2. 将对象,列表的操作,转换成为sql语句
  3. 将sql查询的结果转换为对象、列表

例如:

我们有个表Users
id   username
1     张三
我们想获取张三
# select * from Users where id = 1;
ob = Users.objects.get(id = 1)
# ob 是一个对象  objects
name = ob.username
如果我们想获取所有数据
# select * from Users;
obs = Users.objects.all()
# obs的结果是一个列表[objects,objects....]
为什么要用模型?

MVC 解耦 处理数据 轻松控制

模型的使用
  1. 安装数据库 和 pymysql

  2. 在数据库中建立一个库 字符集 utf-8

  3. setting.py

    1. DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'mydb',#选择数据库的名,请确认你的mysql中有这个库
              'USER': 'root',
              'PASSWORD': '123456',
              'HOST': 'localhost',
              'PORT': '3306',
              }
      }
      
  4. mysite/init.py

    1. import pymysql
      pymysql.install_as_MySQLdb()
      
  5. 模型的定义 在myweb/models.py

    1. 确定当前应用myweb是否在settings.py文件中配置

    2. INSTALLED_APPS = [
          'django.contrib.admin',
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.messages',
          'django.contrib.staticfiles',
          'myweb', # 这里是我们的app
      ]
      

      定义模型

      from django.db import models
      
      class Users(models.Model):
          username = models.CharField(max_length=32)
          password = models.CharField(max_length=32)
          email = models.CharField(max_lenght=100)
          age = models.IntegerField()
          def __str__(self):
              return self,username
      class Stu(models.Model):
          sname = models.CharField(max_length=50)
          age = models.IntegerField()
          # 通过定义元选项,可以自定义表名
          class Meta():
              db_table = 'Stus'  # 那么表名接受自定义
          # 添加字段的后两个选择
          sex = models.CharField(max_length=50,[default='',null=])
      # 默认自动添加自增主键id,而且默认每个字段不能为空,所以在新加入字段的时候,会出现两个选择
      # 1 给现有的数据添加同统一默认值
      # 2 退出添加字段,修改字段属性,给定默认值,或者允许为空
      # 可以更改字段的名字,但是更改数据类型,很容易出现错误
      
  6. 生成迁移文件

    1. python3 manage.py makemigrations
  7. 执行迁移动作

    1. python3 manage.py migrate
  8. 生成很多表 但是只有myweb_users是我们主动创建的

注意:如果没有指定表名,那么默认是应用名_类名的全小写

操作模型

所有的操作都是视图函数去执行,所以,我们需要将models.py文件导入到views.py文件之中

在views.py中加入 from . import Users,Stu

views.py中的查询操作
def mod_test(request):
	obs = Users.abjects.all()
    print(obs)
    # 结果是个查询集  可以说一个列表
    # <Queryset [<Users: Users object>,<Users: Users object>]>
    
    # 如果在模型中定义 __str__()魔术方法,返回self.username 那么print,或者str转换会显示详细的信息
    
    
views.py中的添加操作
def addtest(request):
    # 实例化Users对象,这个对象对应着表中的一条记录
    ob = Users()
    ob.username = '李四'
    ob.email = 'ls@qq.com'
    ob.age = 28
    ob.save()
    # 或者
    data = {'username':'王五''email':'ww@qq.com','age':26}
    ob = Users.objects.create(**data)
    

    
属性命名规则
  • 不可以使用保留关键字
  • 不可以使用双下划线
属性定义
  • 模型的属性就是字段,而且需定义字段类型
  • 导入from django.db import models
  • 通过models.xxxField关键字创建属性
  • 数据删除只做逻辑删除,不做物理删除,通过isDelete属性结合布尔值,标记为逻辑删除(这个标记在python中是True和False在数据库中是1和0)

增删改查

model配置
class Vipuser(models.Model):
    username = models.CharField(max_length=50)
    email = models.CharField(max_length = 100)
    phone = models.CharField(max_length = 11)
    age = models.IntegerField()
    sex = models.CharField(max_length=1)
    # 添加时间
    addtime = models.DateTimeField(auto_now_add=True)
路由设置:
# 会员管理

<路由>
# 显示添加操作的表单
url(r'^user/add/$',views.user_add,name='useradd'),
# 执行添加的操作并且跳转
url(r'^user/insert/$',views.user_insert,name='userinsert'),
# 执行显示列表操作
url(r'^user/list/$',views.user_list,name='userlist'),
# 执行删除操作
url(r'^user/del/(?P<uid>[0-9]+)/$',views.user_del,name='userdel'),
# 执行修改前form表单展示操作
url(r'^user/edit/$',views.user_edit,name='useredit'),
# 执行点击修改后修改数据操作
url(r'^user/update/$',views.user_update,name='userupdate'),


views视图函数
<views函数>
# 返回表单页面
def user_add(request):
    return render(request,'add.html')




# 执行添加操作
def user_insert(requers):
    # 获取数据
    data = request.POST.dict()
    # 删除csrf验证码
    data.pop('csrfmiddlewaretoken')
    # 创建数据
    try:
        # 注意:先将Vipuser这个model导入到views.py这个脚本,使用reverse做动态反向解析要导入包
        # from django.core.urlresolvers import reverse
        ob = Vipuser.objects.create(**data)
        return HttpResponse('<script>alert("success");location.href="'+reverse('userlist')+'"</script>')
    except:
        return HttpResponse('<script>alert("fail");location.href="'+reverse('useradd')+'"</script>')
    
    
    
# 执行列表上显示数据
def user_list(request):
    # 获取数据
    data = Vipuser.objects.all()
    # 分配数据  为什么要设置一个字典?  因为render的第三个参数要求传入一个字典
    context = {'ulist':data}
    # 解析模板
    return render(request,'user/list.html',context)



# 执行删除操作
def user_del(request,uid):
    try:
        # 获取要删除的用户对象
        ob = Vipuser.objects.get(id=uid)
        # 将获取的数据删除
        ob.delete()
        # 提示,并跳转到列表页
        return HttpResponse('<script>alert("删除成功");location.href="'+reverse('userlist')+'"</script>')
    except:
        # 失败跳转到添加页面
        return HttpResponse('<script>alert("删除失败");location.href="'+reverse('useradd')+'"</script>')
    
    
    
# 执行修改前form表单展示操作
def user_edit(request):
    # 从a标签的?uid={}拼接部分获取uid
    uid = request.GET.get('uid')
    # 获取单条数据
    ob = Vipuser.object.get(id=uid)
    # 分配数据
    context = {'uinfo':ob}
    # 解析模板
    return render(request,'user/edit.html',context)


#执行修改操作
def user_update(request):
    try:
        # 获取数据
        uid = request.POST['uid']
        ob = Vipuser.objects.get(id=uid)
        # 依次修改
        ob.username = request.POST['username']
        ob.email = request.POST['email']
        ob.sex = request.POST['sex']
        ob.age = request.POST['age']
        ob.phone = request.POST['phone']
        # 保存
        ob.save()
        # 提示并且返回list页面
        return HttpResponse('<script>alert("修改成功");location.href="'+reverse('userlist')+'"</script>')
    except:
         return HttpResponse('<script>alert("修改失败");location.href="'+reverse('useradd')+'"</script>')
html页面
首页
<ul>
    <li><a href="{% url 'useradd' %}">会员添加</a></li>
    <li><a href="{% url 'userlist' %}">会员列表</a></li>
</ul>
表单页面
<form action='{% url "userinsert" %}' method='POST'>
	<!-- csrf_token 验证加强post传输的安全 -->
    {% csrf_token %}
    用户名:<input type="text" name="username"><br>
    邮箱:<input type="text" name="email"><br>
    手机号:<input type="text" name="phone"><br>
    年龄:<input type="text" name="age"><br>
    性别:
    <input type="radio" name="sex" value="0"><input type="radio" name="sex" value="1"><br>
    <button>添加</button>
</form>

表格页面
<center>
    <table border="1px" cellspacing="0" width="800px">
        <tr>
            <th>ID号</th>
            <th>姓名</th>
            <th>邮箱</th>
            <th>手机号</th>
            <th>年龄</th>
            <th>性别</th>
            <th>创建时间</th>
            <th>操作</th>
        </tr>
        {% for i in ulist %}
        <tr>
            <td>{{ i.id }}</td>
            <td>{{ i.username }}</td>
            <td>{{ i.email }}</td>
            <td>{{ i.phone }}</td>
            <td>{{ i.age }}</td>

            <td>{% if i.sex == '0' %}女{% else %}男{% endif %}</td>
            <!-- |date:这里用到了django的时间过滤器,将时间格式化输出 -->
            <td>{{ i.addtime|date:'Y-m-d H:i:s' }}</td>
            <td><a href="{% url 'userdel' i.id %}">删除</a> |
                <a href="{% url 'useredit' %}?uid={{ i.id }}">修改</a>
            </td>
        </tr>
        {% endfor %}
    </table>
</center>
edit页面
<center>
    <form action="{% url 'userupdate' %}" method="post">
        <!-- csrf_token 验证加强post传输的安全 -->
        {% csrf_token %}
        <input type="hidden" name="uid" value="{{ uinfo.id }}">
        用户名:<input type="text" name="username" value="{{ uinfo.username }}"><br>
        邮箱:<input type="text" name="email" value="{{ uinfo.email }}"><br>
        手机号:<input type="text" name="phone" value="{{ uinfo.phone }}"><br>
        年龄:<input type="text" name="age" value="{{ uinfo.age }}"><br>
        性别:
        {% if uinfo.sex == '0' %}
        <input type="radio" name="sex" value="0" checked><input type="radio" name="sex" value="1">男
        {% else %}
        <input type="radio" name="sex" value="0"><input type="radio" name="sex" value="1" checked>男
        {% endif %}
        <br>
        <button>修改</button>
    </form>
</center>
配置文件时区修改
LANGUAGE_CODE = 'en-us'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'    # 亚洲/上海

USE_I18N = True

USE_L10N = True

USE_TZ = False                 # 原来为True  改为  False

模型关系

一对一

模型之间的一一对应关系

外键有物理外键和逻辑外键,物理外键是单独设立的外键字段,可以在两个表的任意一个表中,逻辑外键一般是使用id号的一一对应关系

屋里外键的优点和缺点都是解耦,缺点在于,删除某个数据的时候如果这个数据是被依赖的外键,那么将无法删除,所以要先删除关系,再删除数据

例如:

model模型

# 现在有两张表,第一张是用户的主要信息,第二张是详细信息,两张表的数据是一一对应的关系

class Vipuser(models.Model):
    username = models.CharField(max_length=50)
    email = models.CharField(max_length=100)
    phone = models.CharField(max_length=11)
    age = models.IntegerField()
    sex = models.CharField(max_length=1)
    addtime = models.DateTimeField(auto_now_add=True)
    

    
# 模型关系,建立一个UserInfo表来记录详细信息
# 在副表userinfo中添加一对一关系,关联vipuser主表
class UserInfo(models.Model):
    # 一对一关系第一个参数是 所关联的模型名称,第二个是是否关联删除
    uid = models.OneToOneField(Vipuser, on_delete=models.CASCADE)
    xueli = models.CharField(max_length=10)
    yuanxiao = models.CharField(max_length=20)
    jiguan = models.CharField(max_length=20)

路由




 # 模型关系1对1
    url(r'model/one/$', views.one, name='one'),
    url(r'model/two/$', views.two, name='two'),
    url(r'model/three/$', views.three, name='three'),
views视图函数


# 模型关系1对1


def one(request):
    # 添加
    # 创建用户
    data = {
        'username': '李四',
        'age': 18,
        'email': 'lis@qq.com',
        'phone': '11111',
        'sex': 1,
    }
    u = Vipuser.objects.create(**data)
    # 创建详情  在django中外键是能给实例化的对象,不能直接给id数字
    uidata = {
        'uid': u,
        'xueli': '本科',
        'yuanxiao': '山东大学',
        'jiguan': '山东',
    }
    ui = UserInfo.objects.create(**uidata)
    return HttpResponse("模型关系一对一")





def two(request):
    # 删除用户  删除用户的时候也将关联删除用户的详情,但是如果删除副表数据,却不会删除主表数据,删除主表数据,会删除附表数据
    u = Vipuser.objects.first()
    u.delete()
    return HttpResponse('执行了删除的操作')






def three(request):
    # 查询可以根据主表查附表,也可以根据副表查主表
    # 根据用户查详情
    u = Vipuser.objects.first()
    # 获取用户的Username
    print(u.username)
    # 获取用户的详情的yuanxiao,主表获取副表的时候直接对象后面跟表名然后跟字段就行
    print(u.userinfo.yuanxiao)
    u2 = UserInfo.objects.first()
    # 根据副表查询主表就需要在附表对象的后面跟外键字段,再跟要查询的主表字段
    print(u2.uid.sex)
    print(u2.xueli)
    return HttpResponse('执行了查询的操作')
一对多

一个a表数据对应多个b表数据,多个b表数据对应一个a表数据

例如:

一个班级有多个学员,多个学员都在一个班级

一个新闻分类有多个新闻,多个新闻是一个类新闻

一个商品分类下有多个商品

例如:

model模型   类别  和  商品的一对多关系
# 模型的一对多关系
# 类别
class Types(models.Model):
    name = models.CharField(max_length=10)


# 商品
class Goods(models.Model):
    # 第一个参数to指向的是Types这个主表,to_field参数指向的主表中的对应的字段
    tid = models.ForeignKey(to='Types', to_field='id')
    title = models.CharField(max_length=255)
    price = models.IntegerField()

    def __str__(self):
        return self.title

url路由
 url(r'model/duoone/$', views.duo_one, name='duoone'),
    url(r'model/duotwo/$', views.duo_two, name='duotwo'),
    url(r'model/duothree/$', views.duo_three, name='duothree'),
    url(r'model/duothree2/$', views.duo_three2, name='duothree2'),
views视图函数


# 一对多的关系
# 添加
def duo_one(request):
    t = Types.objects.create(**{'id': 3, 'name': '电视'})

    g1 = Goods.objects.create(**{'title': '小米电视', 'price': 3999, 'tid': t})
    g1 = Goods.objects.create(**{'title': 'TCL电视', 'price': 1999, 'tid': t})

    return HttpResponse('添加数据成功')


# 删除
def duo_two(request):
    # 删除分类之后,相对应的商品也会被删除,但是删除商品后不会影响分类
    t = Types.objects.first()
    t.delete()
    return HttpResponse('删除了一个分类')


# 查询
def duo_three(request):
    # 根据分类获取分类下的商品
    t = Types.objects.first()
    print(t.name)
    print(t.goods_set.all())
    print(t.goods_set.count())
    return HttpResponse("执行了一次查询")


def duo_three2(request):
    # 根据商品查询商品的分类
    g = Goods.objects.last()
    print(g.title)
    print(g.tid.name)
    return HttpResponse('执行了一次查询操作')
多对多

一个班级有多个老师,一个老师带多个班级

一本书有多个标签,一个标签有多本书

books 【book表】

id title author

tags 【tag表】

id name

books_tags 【所依赖的第三张表】

bookid tagid

多对多的关系,将关系连接字段放在两个模型的任意一个表中都可以,没有主附表之分

例如:

model模型


# 模型多对多关系
# book表
class Books(models.Model):
    title = models.CharField(max_length=100)

    def __str__(self):
        return self.title


# tag表
class Tags(models.Model):
    name = models.CharField(max_length=100)
    # 多对多关系连接字段  ,参数to指向关联的表
    bid = models.ManyToManyField(to='Books')

    def __str__(self):
        return self.name
路由


    url(r'model/bookone/$', views.book_one, name='bookone'),
    url(r'model/booktwo/$', views.book_two, name='booktwo'),
    url(r'model/bookthree/$', views.book_three, name='bookthree'),
views视图函数


# 多对多模型的添加
def book_one(request):
    # 创建三本书,和 三个标签
    b1 = Books.objects.create(**{'title': '《python从零开始》'})
    b2 = Books.objects.create(**{'title': '《php兄弟连》'})

    t1 = Tags.objects.create(**{'name': 'IT编程'})
    t2 = Tags.objects.create(**{'name': 'python'})
    t3 = Tags.objects.create(**{'name': 'php'})
    # 给标签添加书的对应关系add和set两个方法效果一样
    t1.bid.set([b1, b2])
    t2.bid.add(b1)
    t3.bid.add(b2)
    '''
    或者给书添加标签的对应关系,这两种方式都可以
    b1.tags_set.set([t1,t2])
    b2.tags_set.set([t1,t3])
    清空某个对象的所有关系
    b = Books.objects.first()
    将b这本书的对应关系清空
    b.tags_set.clear()
    '''
    return HttpResponse("执行了多对多的添加操作")

# 多对多的删除操作,删除任意一方对另外一方不影响,只会将关系表中的关系连带的删除


# 查询   获取某本书的所有的标签
def book_two(request):
    # 获取书对象
    b = Books.objects.last()
    print(b.title)
    print(b.tags_set.all())
    return HttpResponse('执行了一次根据书查询标签的操作')


# 获取一个标签下面的所有书
def book_three(request):
    # 获取书对象
    t = Tags.objects.first()
    print(t.name)
    print(t.bid.all())
    return HttpResponse('执行了一次根据标签查询书的操作')


views视图

简单的返回信息或者html标签
from django.http import HttpResponse
import datetime

def current_datetime(request)
	now = datetime.datetime.now()
    html = '<html><body>It is now %s.</body></html>'%now
    return HttpResponse(html)
返回常见的错误
from django.http import HttpResponseNotFound,HttpResponse,Http404

# 直接返回404,不加载404模板页面
return HttpResponseNotFound('<h1>访问的页面不见了</h1>')
# 直接返回一个status状态码
return HttpResponse(status=403)404 500
# 返回一个自定义在templates下的404页面
raise Http404("Poll doex not exist")
重定向

重定向就是通过各种方式将网络请求转向其他位置

from django.shortcuts import redirect
from django.core.urlresolvers import reverse

# redirect的重定向需要一个url地址
return redirect(reverse('urlname'))
# 通过JavaScript重定向
return HttpResponse('<script>alert("xxx");location.href="+reverse('urlname')+"</script>')
# 加载一个提醒信息的跳转页面~~还有多久将执行跳转,计时器
context = {'info':'数据添加成功','u':'/userindex'}
return render(request,'info.html',context)
request对象的几个属性
request.path       # 获取请求路径str
request.method     # 获取请求方法str
request.encoding   # 获取提交数据的编码格式str
request.GET        # 获取GET方式提交数据的类字典对象
request.POST       # 获取POST方式体检数据的类字典对象
request.FILES      # 获取文件上传提交的类字典对象
request.COOKIS     # 一个标准的python字典,包含所有cookie  键值对
request.session    # 获取可读写的session类字典对象
cookie

储存在浏览器中的状态信息,是一个类字典

用法:

设置cookie

# 获取HttpResponse对象
res = HttpResponse()
# 为对象设置cookie  不可使用中文
res.set_cookie('name','zhangsan')
# 返回相应对象
return res



获取cookie
# 读取
a = request.COOKIES.get('name',None)

if a:
    return HttpResponse('cookie的读取:'+a)
else:
    return HttpResponse('cookie不存在')
session

session是储存在服务器数据库中的一个类字典的状态信息

方法:

# 设置session
request.session.['Vipuser'] = {'name':'张三','age':18,'sex':0}
# session获取
request.session.get('Vipuser',None)
# 在不中断会话的前提下可以继续添加session,就是一个字典套字典


# 删除session三个方式
# 只删除一个键值对
del request.session['Vipuser']
# 删除会话,不删除记录
request.session.clear()
# 删除会话也删除记录
request.session.flush()
验证码-是块砖
# 验证码
def verifycode(request):
    #引入绘图模块
    from PIL import Image, ImageDraw, ImageFont
    #引入随机函数模块
    import random
    #定义变量,用于画面的背景色、宽、高
    bgcolor = (random.randrange(20, 100), random.randrange(
        20, 100), 255)
    width = 100
    height = 25
    #创建画面对象
    im = Image.new('RGB', (width, height), bgcolor)
    #创建画笔对象
    draw = ImageDraw.Draw(im)
    #调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)
    #定义验证码的备选值
    # str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
    str1 = '123456789'
    #随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]
    #构造字体对象
    font = ImageFont.truetype('FreeMono.ttf', 23)
    #构造字体颜色
    fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
    #绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    #释放画笔
    del draw
    #存入session,用于做进一步验证
    request.session['verifycode'] = rand_str
    #内存文件操作
    import io
    buf = io.BytesIO()
    #将图片保存在内存中,文件类型为png
    im.save(buf, 'png')
    #将内存中的图片数据返回给客户端,MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'image/png')
四级联动
models模型

class City(models.Model):
	name = models.CharField(max_length=255)
    level = models.IntegerField()
    upid = models.IntegerField() 
    class Meta:
        db_table = 'citys'
# 路由

url(r'^showcity/$',views.showcity,name='showcity'),
url(r'^getcity/$',views.getcity,name='getcity'),
# views视图函数

def showcity(request):
    # 查询一级城市
    data = City.objects.filter(level=1)
    context = {'data':data}
    return render(request,'city.html',context)


def getcity(request):
    # 根据请求发送过来的id做uid查询
    uid = request.GET.get('id')
    # 根据id获取数据
    data = City.objects.filter(upid=uid).values()
    # 返回json数据
    return JsonResponse(list(data),safe=False)
<select>
    <option>--请选择--</option>
    {% for i in data %}
    <option value='{{ i.id }}' >{{ i.name }}</option>
    {% endfor %}
</select>
<script src='/static/js/jq.js' ></script>
<script>
	// 获取所有的select
    $('select').live('change',function(){
        var id = $(this).val();
        // 清楚后面的杂质元素
        $(this).nextAll().remove();
        // 发送ajax请求
        $.get("{% url 'getcity' %}",{'id':id},function(data){
            // 判断data是否有数据
            if (data.length==0){return};
            var sel = $('<select></select>');
            var ops = '<option>--请选择--</option>';
            for (var i=0;i<data.length;i++){
                ops += '<option value='+data[i].id+' >'+data[i].name+'</option>';
            };
            // opd插入到sel
            sel.html(ops);
            // sel追加
            $('body').append(sel);
        },'json')
    })


</script>



# 配置文件设置静态文件的路径


STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static'),
]

template模板

配置模板引擎—seeting.py
TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR,'templates')],            # 主要是这里,配置模板的路径
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
常用模板语法
  1. 变量

    • 变量输出

      {{ var }}
      
    • 注意:

      • 变量数据来源是后台对模板的解析以及数据分配
      • 变量命名规范
      • var.avr.var解析为:
        • 字典解析
        • 对象属性解析
        • 索引解析
      • 变量如果不存在,自动插入空字符串
      • 模板中调用方法不能传递参数
  2. 标签语法

    {% tag %}
    
    • 作用:

      • 动态创建文本
      • 循环或者流程控制
      • 加载外部模板
    • for 标签

      {% for i in arr %}
      {% endfor %}
      
    • if 分支结构

      {% if ... %}
      {% elif... %}
      {% else %}
      {% endif %}
      
    • comment多行注释标签

      {% comment %}
      {% endcomment %}
      
    • include标签 加载模板,并且以标签内参数进行渲染

      {% include 'base/index.html' %}
      
    • url 反向解析

      {% url 'urlname' %}
      
    • csrf 跨站请求

      {% chrf_token %}
      
过滤器
{{ var|uppr }}    {{ 变量名|过滤器 }}


{{ HTML|safe }}    关闭html安全转译

{% if list1|length>1 %}   结合if标签使用
{{ name|lower|upper }}    过滤器的串联使用
{{ list|join:',' }}       过滤器传递参数  使用''引起来
{{ value|default:'默认值' }}  在变量空值或者False的时候返回默认值
{{ value|date:'Y-m-d H:M:s' }}  格式化显示时间
模板运算 不太好用
{{ value|add:10 }}   +10
{{ value|add:-10 }}  -10
{% widthratio 5 1 100 %}   5 × 100
{% widthratio 5 100 1 %}   5 ÷ 100
自定义标签个自定义过滤器

创建一个templatetags的目录【创建在定义的app目录中】

在这个目录中创建一个pagetag.py文件----文件名自定义

内容:

from django import template
register = template.Library()

# 自定义过滤器
@register.filter
def my_upper(val):
    print(val,'应用了一次自定义的过滤器')
    return val.upper()

# 自定义标签
from django.utils.html import format_html
@register.simple_tag
def jiafa(a,b):
    res = int(a) + int(b)
    return res
使用自定义的过滤器和标签

首先将定义的文件导入到当前的文档之中
{% load pagetag %}
<ul>
	<li>使用自定义的过滤器:{{ val|my_upper }}</li>
	<li>使用自定义的标签:{% jiafa 10 20 %}</li>
</ul>
文档片段的重复引用
  • 在templates目录中创建include目录,用来存重复使用的文档片段
  • 目录中的每一个html文件是一个代码片段
  • 在文档之中使用{% includ ‘xxx.htm’ %}就可以将片段导入此文档
模板的继承
  • 减少页面内容重复定义,同一段内容多次使用
  • 直观的是网站的头和尾两个部分,定义在父模板中,子模板继承使用
  • 在这里会用到block标签,预留在父模板中,以便子模板插入自己的内容
  • 父模板是放在templates目录下你的extends目录之中
  • 在此目录中创建父模板base.html
定义在父模板中的block预留位置
{% block block_name %}
可以在这里定义默认值
如果不定义,默认空字符串
{% endblock %}
子模板  导入父模板  并且在预留位置插入内容

{% extends 'base.html' %}  导入模板的位置,在文档头部

{% block block_name %}
<ul>
    <li>插入了自己的内容</li>
</ul>
{% endblock %}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值