自定义标签和过滤器,模板的导入和继承,静态文件相关,模型层相关操作

本文回顾了上节的日志记录功能,接着详细讲解了Django中如何自定义标签和过滤器,模板的导入与继承,如创建base.html母版并由login.html继承。此外,介绍了静态文件的处理,inclusion_tag的运用,以及模型层的单表操作,包括字段和字段参数,单表的增删查改操作。
摘要由CSDN通过智能技术生成

一.上节回顾

1 写一个装饰器,用在视图函数上,不管前端用什么编码方式传数据,数据部分都从request.data中取(drf框架)
# views.py
'''
from django.shortcuts import render, HttpResponse

# Create your views here.
import json


def parse_json(func):
    def inner(request,*args, **kwargs):
        # 不管是什么编码方式,从request.data中可以把字典取出来(post提交的数据)
        try:
            # 3.6之前,报错(json.loads只能loads字符串)
            # 你在工作中遇到的问题及如何解决的?
            res = json.loads(request.body)
            ss = bytes(request.body,encoding = 'utf-8')
            request.data = res
        except Exception as e:
            # 如果出了异常,说明是urlencoded或者是form-data编码
            request.data = request.POST
        res = func(request,*args, **kwargs)
        return res

    return inner

@parse_json
def index(request):
     print(request.data)
     return HttpResponse('ok') 
'''

2 记录日志功能
3 django响应头的设置
'''
def index(request):
	# 设置响应头
	# obj=render(request,'index.html')
	# obj=JsonResponse()
	obj=HttpResponse('OK')
	obj['name']='lqz'
	obj['age']='19'
	return obj

记录日志功能:models.py

class Logs(models.Model):
	id=models.AutoField(primary_key=True)
	path=models.CharField(max_length=32)
	visit_time=models.DateTimeField(max_length=32)
	user_agent=models.CharField(max_length=128)
	ip=models.CharField(max_length=32)

记录日志功能:views.py

from app01 import models
import datetime
def index(request):

	visit_time=datetime.datetime.now()
	ip=request.META.get('REMOTE_ADDR')
	user_agent=request.META.get('HTTP_USER_AGENT')
	path=request.get_full_path()
	models.Logs.objects.create(visit_time=visit_time,user_agent=user_agent,path=path,ip=ip)

	return HttpResponse('ok')
1 模板层,templates xx.html 每一个web框架,都应该支持渲染模板
2 DTL
3 django中渲染模板的两种方式
	-render(request,'模板.html',context={})
	-本质:打开模板文件,字符串替换,return HttpResponse('替换完的字符串')
	-第二种:手动作(页面静态化,伪静态:seo优化)
4 前后端交互的编码格式:urlencoded,form-data,json
	-request.POST只能取出urlencoded,form-data两种编码的数据
	-json格式,request.POST取不出来,从body中取,自行处理
5 模板语法之变量
	-locals()
	-{{变量}}  # 相当于print打印
	-可以执行函数,但是不能加括号(不能传参数)
6 模板语法之深度查询
	-字典,列表	dic.name	ll.1  ll.3.name
	-对象		对象.test	对象.hobby.id
7 模板语法之过滤器
	-{{'参数1'|过滤器名字:参数2}}
	-有很多(至少传一个参数,最多传2个参数)
	-date,safe
	-'asskdjfhgh'|slice:'2:6'
8 模板语法之标签
	-{% %}
	-for: (多层for)
		{% for i in ll %}
			{{forloop}}
			{%empty%}
			当为空时,会显示
		{% endfor %}
	-if
		{% if 条件 %}
		{% elif 条件 %}
		{% else 条件 %}
		{% endif 条件 %}
	-with:重命名
	-csrf:{% csrf_token %} 会生成一个隐藏的input

二.今日内容

(1)自定义标签和过滤器

1 自定义过滤器
	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
	-第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
	-第三步:在包内,新建py文件(:my_tags.py)
	-第四步:写代码(过滤器)
		from django import template
		register = template.Library()
		@register.filter
		def my_upper(value):
			return value.upper()
	-第五步使用:(模板),先load,再使用
		{% load my_tags %}
		{{ 'aa'|my_upper }}
2 自定义标签
	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
	-第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
	-第三步:在包内,新建py文件(:my_tags.py)
	-第四步:写代码(过滤器)
		from django import template
		register = template.Library()
		@register.simple_tag
		def my_csrf():
			import uuid
			res = uuid.uuid4()
			return mark_safe('<input type="hidden" name="csrfmiddlewaretoken" value="%s">'%res)
	-第五步使用:(模板),先load,再使用
		{% load my_tags %}
		{% my_csrf %}
		{% my_tag 1 3 4 %}

(2)模板的导入和继承

1 模板的导入
	-第一步:新建一个 xx.html,把好看的模板写入
	 <div class="panel panel-danger">
            <div class="panel-heading">
                <h3 class="panel-title">重金求子</h3>
            </div>
            <div class="panel-body">
                详情点击:<a href="http://www.baidu.com">疯狂点我</a>
            </div>
     </div>
   -第二步:在你想用的地方
   {% include 'xx.html' %}  
 
 2 模板的继承(母版)
 	-第一步:写一个母版,写空盒子
 	{% block top %}
 	{% endblock %}
 	-第二步:某个页面要使用模板,引入,扩写盒子
 	{% extends 'base.html' %}
 	{% block content %}
 		login页面
 	{% endblock %}

写一个母版base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="../static/bootstrap/css/bootstrap.min.css">
    {% block css %}
    
    {% endblock %}
</head>
<body>
<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
    <div clss="row">
        <div class="col-md-3">
            <div class="list-group">
                <a href="/home/" class="list-group-item disabled">
                    首页
                </a>
                <a href="/login/" class="list-group-item">登录</a>
            </div>
        </div>
        <div class="col-md-9">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    {% block content %}
                    <div class="jumbotron">
                        <h1>Hello, world!</h1>
                        <p>...</p>
                        <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
                    </div>
                    {% endblock %}
                </div>
            </div>
        </div>
    </div>
</div>
{% block js %}

{% endblock %}
</body>
</html>

login.html :继承母版

{% extends 'base.html' %}
{% block css %}
    <style>
        h1 {
            color: red;
        }
    </style>
{% endblock %}
{% block content %}
    <h1 class="text-center">登录页面</h1>
    <form action="">
    <p>username: <input type="text" class="form-control"></p>
    <p>password: <input type="text" class="form-control"></p>
    <p><input type="submit" class="btn btn-danger"></p>
    </form>
{% endblock %}

{% block js %}
    <script>
        alert('登录页面')
    </script>
{% endblock %}

(3)静态文件相关

# 三种方式
	第一种:<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
	第二种:
	{% load static %}
	<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
	第三种:
	{% load static %}
	<link rel="stylesheet" href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css">

# 特殊用法
	{% load static %}
	{% static "image/hi.jpg" as myphoto %}
	<img src="{{ myphoto }}"></img>
	
	{% load static %}
	{% get_static_prefix as static %}
	<img src="{{static}}image/hi.jpg" alt="Hi!"/>

(4)inclusion_tag的使用

# 可以生成一片模板中的代码块
# 使用:5步
	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
	-第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
	-第三步:在包内,新建py文件(:my_tags.py)
	-第四步:写代码(inclusion_tag)
	# inclusion_tag,传一个模板文件
	@register.inclusion_tag('left.html')
	def left(num):
		# dic={0:第0页,1:第1页,2:第2页}
		dic = {i:'第%s页'%i for i in range(num)}
		# 固定返回的必须是字典
		print(dic)
		return {'data':dic}
	@register.inclusion_tag('beautiful.html')
	def beautiful(title,url):
		return {'title':title,'url':url}
	-第五步使用:(模板),先load,再使用
		{% load my_tags %}
		{% left 5 %}
		{% beautiful '名字' '地址' %}
# 它跟tag有什么不同?
	-tag需要在代码中写html的东西
	-inclusion_tag代码跟模板分离

my_tags.py

from django import template
from django.utils.safestring import mark_safe
register=template.Library()

# 自定义inclusion_tag
@register.inclusion_tag('left_menu.html')
def left(n):
	data=["第{}项".format(i) for i in range(n)]
	return locals()

@register.inclusion_tag('beautiful_egon.html')
def beautiful(title,url):
	return {'title':title,'url':url}

## 通过tag实现beautiful的功能
@register.simple_tag
def tab_beautiful(title,url):
	return mark_safe('''
	<div class="panel panel-danger">
    <div class="panel-heading">
        <h3 class="panel-title">%s</h3>
    </div>
    <div class="panel-body">
        详情点击:<a href="%s">疯狂点我</a>
    </div>
	</div>
		''' % (title, url))

beautiful_egon.html

<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<div class="panel panel-danger">
    <div class="panel-heading">
        <h3 class="panel-title">{{ title }}</h3>
    </div>
    <div class="panel-body">
        详情点击:<a href="{{ url }}">疯狂点我</a>
    </div>
</div>

index.html

{% load my_tags %}

{% left 10 %}
{% beautiful '名字' 'http://www.GitHub.com' %}

<hr>

{% tab_beautiful 'xxx' 'http://www.baidu.com' %}

(5)模型层之单表操作

(6)字段和字段参数介绍

class Book(models.Models):
	# 如果不写id,会默认一个id,并且自增
	# primary_key=True 表示该字段是主键,一个表中只能有一个主键
	# id = models.AutoField(primary_key=True)
	# varchar类型,长度
	# 字段是否可以为空:null=True,可以为空
	# 默认值:default='未知书名',如果没穿,默认是它
	# 设置索引:db_index=True 表示该字段是辅助索引
	# 是否唯一:unique=True 表示唯一
	name=models.CharField(max_length=32,null=True,defualt='未知书名',db_index=True,unique=True)
	# float类型
	# max_digits 最大长度是5  4567.5
	# decimal_places=2 小数点后两位  23.56  999.99
	price=models.DecimalField(max_digits=5,decimal_places=2)
	# DateTimeField年月日时分秒
	# auto_now=True  新增,默认使用当前时间
	# auto_now_add=True  修改,设置当前时间
	publish_date=models.DateTimeField(auto_now=True)
	publish=models.CharField(max_length=32)
	

(7)单表增加

两种方式
第一种:
models.Book.objects.create(name='xxx',price=10.34,publish='南京出版社')
第二种:
book=models.Book(name='yyy',price=11.34,publish='南京出版社')
book.save()

(8)单表查询

# 查询名字叫xxx的书
from app01 import models
def book(request):
	# models.Book.objects.create(name='xxx',price=10.34,publish='南京出版社')
	# book=models.Book(name='yyy',price=11.34,publish='南京出版社')
	# book.save()

	# 查询所有
	res=models.Book.objects.all()
	print(res)
	# 查询名字叫xxx的书(是个列表:QuerySet)
	res = models.Book.objects.filter(name='xxx')
	res = models.Book.objects.filter(name='xxx')[0]
	res = models.Book.objects.filter(name='xxx').first()

	# 查询名字叫xxx的书(就是book对象),如果没有或者有多个,都报错
	# 查询结果必须有且仅有一个才正常,否则报错
	res=models.Book.objects.get(name='sss')

	print(res.name)
	return HttpResponse('两本书保存成功')

(9)补充

encode和decode记混了

1 方式一:
	a='sadjfh'  # type str
	a.提示
2 方式二:
	ss = str(bytes数据,encoding='utf-8')
	ss_bytes = bytes('字符串变量',encoding = 'utf-8')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值