欢迎食用『主界面』~,这里是赵苦瓜的看板娘desu~

#
【点滴记录】Django框架的入门 - 第三篇(查询、切片、模板语法)
首页 > 点滴记录    作者:赵苦瓜   2021年1月22日 8:10 星期五   热度:4452°   百度已收录  
时间:2021-1-22 8:10   热度:4452° 

第二篇主要讲了修改数据库的操作和模型层的一些知识,戳链接==>https://blog.jixiaob.cn/?post=39

————————————————————————————————————————

用户查询验证

def get_user(request):
    username = 'Sunck'
    password = '1d20'
    users = User.objects.filter(u_name=username)
    if users.count():       # 这里也可以用users.exists()判断是否存在
        user = users.first()             # 这里的u_name字段设定为了不可重复,所以first和last都行
        if user.u_password == password:
            print("获取用户信息成功")
        else:
            print('密码错误') else:
        print("用户不存在")
    return HttpResponse("获取成功")

————————————————————————————————————————

限制查询集和查询集的缓存(切片)

这个切片和Python的切片不太一样,下标不能是负数

QuerySet[5:15]获取第五条到第十五条数据,相当于SQL中的limit和offset

def get_users(request):
    users = User.objects.all()[1:3]   # 切片获取第二条和第三条数据
    context = {
        'users': users,
    }
    return render(request, 'userlist.html', context=context)
此时你打开对应的网址getusers之后,可能还会打开成getuser的网址。

(其实是我忘了加\了)

这是url 和path在Django2.2版本进行的更改导致的,出现上述情况肯定写的是url,改为path即可。记得from django.urls import path。

查询集缓存:每个查询集都包含一个缓存,来最小化调用数据库。不论filter、exclude、all了多少次,都不会真正的去访问数据库。只有在迭代结果集,或者获取单个对象属性的时候,它才会去查询数据库。这种查询叫做懒查询,是为了优化查询和结构。


——————————————————————————————————————————————

字段查询

属性__运算符=值

gt 大于  lt 小于  gte 大于等于 lte 小于等于  in 在某一个集合之中  

contains 包含(类似于模糊查询的like) startswith 以XX开始  endswith 以XX结束    exact精确等于,相当于直接等于   这四个前面可以添加一个i,表示忽略大小写。

isnull   isnotnull是否为空    

  

时间运算符

year  month day week_day  hour  minute  second

filter(lastname__year=2021)

查询快捷:pk,代表主键   filter(pk=1)

Django 中的查询条件有时区问题。可以关闭Django中自定义的时区(settings里面USE_TZ = False)或者在数据库中创建对应的时区表(比较麻烦)


跨关系查询

比如查询哪一个班级里有叫Jack的

首先建立模型

class Grade(models.Model):
    g_name = models.CharField(max_length=16)


class Student(models.Model):
    s_name = models.CharField(max_length=16)
    s_grade = models.ForeignKey(Grade, on_delete = models.CASCADE)
    
当然也可以先查学生中的Jack,再查对应的班级。不过这样比较麻烦。


Django中提供了一种直接查询的方式

def get_grades(request):
    grades = Grade.objects.filter(student2__s_name='Jack')
    for grade in grades:
        print(grade.g_name)
    return HttpResponse('获取成功')


聚合函数

Avg平均值  Count数量  Max最大  Min最小  Sum求和

from django.db.models import Max

Student.objects.aggregate(Max('s_age'))

会返回一个字典


F对象

F对象可以简单的获取到一个模型的属性的值

可以实现一个模型的不同属性的运算操作

比如获取女生人数比男生多的公司

conpanies = Company.object.filter(c_boy_num__lt=F('c_girl_num') - 15 )  # 这里使用了F对象来获取女生人数,后面可以运算


Q对象

常用于组合条件。可以对条件进行封装,封装之后可以支持逻辑运算与(&  and)、或(|  or)、非(~  not)

可以把链式调用改成Q对象

比如上一篇写的:

persons = Person.objects.filter(p_age__gt=50).filter(p_age__lt=80)  # 获取年龄50<年龄<80的人


可以改为:

persons = Person.objects.filter(Q(p_age__gt=50) & Q(p_age___lt=80))
这样可以把多个条件写到一个filter中


模型成员

显性属性:开发者手动书写的属性    隐性属性:开发者没有书写,ORM自动生成的,如objects是一个models.Manager()

如果把隐形属性写成了显性属性,隐形属性就不会自动生成了

比如在其中一个类中声明一个abc_manager = models.Manager()   这样之前的objects就不能用了

另外自定义这个模型管理可以先继承然后自定义属性

在父类中定义一个自己的manager类,继承models.Manager()

在里面定义get_queryset(self)

class Self_manager(models.Manager):
    def get_queryset(self):
        return super(Self_manager, self).get_queryset().filter(is_delete=False)  # 直接在这里面筛选掉删除的


然后上面的abc_manager要改为 abc_manager = Self_manager()  # 当然如果之前都写了objects,这里也可以重新定义一下objects来统一解决



当然也可以在自己写的manager类中写一个造对象的方法:

def create_animal(self, a_name='Chicken'):
    a = self.model()
    a.a_name = a_name
    return a

——————————————————————————————————————————————

Templates模板

在Django中,模板是可以帮助开发者快速生成呈现给用户页面的工具。Django有独有的模板引擎。

模板的处理有加载和渲染两个过程。

# 常规渲染
from django.template import loader


temp = loader.get_template('index.html')
content = temp.render()
return HttpResponse(content)

# 简便写法
from django.shortcuts import render


return render(request, 'index.html')



模板主要由两部分组成——静态的HTML和动态插入的代码段(挖坑、填坑)

模板中的动态代码段除了做基本的静态填充,还可以实现一些基本运算,转换和逻辑

模板中的变量:视图(view)传递给模板数据,遵守标识符规则,语法{{var}}

 如果变量不存在,则插入空字符串


模板中的点语法

grades    grade

字典查询   属性或方法    索引

<ul>
    {% for student in students %}
        <li>{{ student.s_name }}        </li>  # 这里的点是student的属性
    {% endfor %}
</ul>



如果在Student类里面写一个获取名字的函数

    def get_name(self):
        return self.s_name
在HTML模板里面这样用:


<ul>
    
    {% for student in students %}
        <li>  {{ student.get_name }}  </li>    # 这里就是函数的用法
    {% endfor %}

    
    
</ul>


student.0.s_name    返回的是第一个学生的姓名,0就是充当索引的作用。1,第二个,2,第三个……

还可以传入字典,字典.key  可以得到value

模板的小弊端:调用对象方法时不方便传递参数。通常只调用不传参的函数。


标签

模板中的小标签:语法{% tag %}  作用:1.加载外部传入的变量  2.在输出中创建文本 3.控制循环或逻辑

标签分为单标签和成对的标签。成对的标签切记不能省略。

If结构:

# if结构
{% if 表达式 %}
    语句
{% endif %}


{% if 表达式 %}
    语句
{% else %}
    语句
{% endif %}


{% if 表达式 %}
    语句
{% elif 表达式 %}
    语句
{% endif %}


  

for结构

{% for 变量 in 列表 %}
        语句1
    {% empty %}
        语句2
{% endfor %}
当列表为空或不存在时,执行empty之后的语句


forloop是一个循环状态的记录

{{ forloop.counter }}  表示当前是第几次循环,从1开始计数

forloop.counter0  表示当前是第几次循环,从0开始计数

forloop.recounter 表示第几次循环,倒着计数,1结束

forloop.recounter0 表示第几次循环,倒着计数,0结束

forloop.first 布尔值,是否为第一个

forloop.last  布尔值,是否为最后一个


下面代码把第一个的颜色变为了红色。如果空输出Sunck辍学了

<ul>
    {% for student in students %}
        {% if forloop.first %}
            <li style="color: red">{{ forloop.counter }}:{{ student.s_name }} </li>
            {% else %}
                 <li>{{ forloop.counter }}:{{ student.s_name }}        </li>
        {% endif %}
        {% empty %}
        <h1>Sunck辍学了</h1>
    {% endfor %}
</ul>
模板中的注释。这样写不会渲染到页面上


单行注释:{# 注释的内容 #}

多行注释:{% comment %}

                    内容

                {% endcomment %}

乘除

{% widthratio 数 分母 分子 %}   只有乘的操作,写除转化成分数

{% if num|divisibleby:2 %} 如果整除

{% ifequal 值1 值2 %}  如果相等  {% endifequal %}    还有如果不相等{% ifnotequal %}


{% url 'namespace:name' p1 p2 %} URL反向解析

csrf_token 用于跨站请求伪造保护 {% csrf_token %}


过滤器

作用:在显示前修改

加减:add    {{ p.page|add:5 }}  减就是加负数

转换大小写:lower   upper    {{ p.pname|lower }}

过滤器还可以传递参数,参数需要用引号引起来{{ students|join '=' }}    默认值{{ var|default value}}  变量没有值或为False 空会使用默认值     日期转字符串{{ dataVal|date:'y-m-d'}}


HTML转义

将接收到的数据当成普通字符串处理还是当HTML代码渲染的问题

{{ code|safe }}     把code的内容(HTML代码)渲染出来,而不是作为普通文本输出(谨慎使用!可能会出现js注入)


<script type="text/javascript">

alert("你的网站被攻陷了")

var lis = document.getElementsByTagName("li");

for (var i=0; i<lis.length; i++){

    var li = lis[i];

    li.innerHTML="喵喵";

}

</script>


{{% autoescape off %}}      这里吧off改为on就不会渲染出来了

    code

{{% endautoescape %}}


模板继承

关键字block:挖坑 


# base.html
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
{% block header %}
{% endblock %}

{% block banner %}
{% endblock %}

{% block content %}
{% endblock %}

</body>


# home.html 填坑


{% extends 'base.html' %}

{% block header %}
    <h3>哈哈哈,这是一个头</h3>
{% endblock %}


结构标签:

block:块,用来规划布局。首次出现代表规划,第二次出现代表填充以前的规划。

block.super可以继承而不是覆盖,实现增量式操作

{% extends 'home.html' %}

{% block content %}
    <h3>哈哈哈</h3>
{% endblock %}

{% block header %}
    {{ block.super }}
    <h4>听说你很精神</h4>
{% endblock %}


extends:继承模板,可以获取父模板的所有结构。

block + extends :化整为零


include   包含,可以将页面作为一个模块(一部分),嵌入到其它页面中

{%block footer %}

    {% include 'footer.html' %}

{% endblock %}


include + block  由零聚一


三个标签可以混合使用。但是能用第一个搞定的就尽量不要使用include(include效率较低)

在子模板中无法重写父模板里面的内容。


js,css,image等静态文件通常放在static文件夹。

在base.html中外挂css

   {% block ext_css %}

    {% endblock %}
在home_mine中

{% block ext_css %}
    <link rel="stylesheet" href="/static/css/home_mine.css">
{% endblock %}
在home_mine.css中:

h3{
    color: red;
}
然后在settings里面注册一下静态文件路径(别忘了在项目跟目录创建static文件夹):

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

上面的写法一般不推荐,也可以这样写,写成标签式写法的相对路径:

home_mine.html里面:

{% load static %}     # 开头这两个任选一个
{% load staticfiles %}
{% block ext_css %}
    <link rel="stylesheet" href="{% static 'css/home_mine.css' %}">
{% endblock %}

但是debug改为False就不能用了,仅在debug模式可以使用,以后需要自己单独处理。

静态资源要讲究动静分离。





本文作者:赵苦瓜      文章标题: 【点滴记录】Django框架的入门 - 第三篇(查询、切片、模板语法)
本文地址:https://blog.jixiaob.cn/?post=40
版权声明:若无注明,本文皆为“赵苦瓜のBlog~”原创,转载请保留文章出处。

返回顶部    首页    后花园  
版权所有:赵苦瓜のBlog~    站长: 赵苦瓜    程序:emlog   鲁ICP备20030743号-1   鲁公网安备37048102006726 萌ICP备20222268号    sitemap