Django基础篇

Posted fqh202

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django基础篇相关的知识,希望对你有一定的参考价值。

Django基本命令

# 1. 下载Django
pip3 install django

# 2. 创建一个Django对象,在终端上执行,必须添加环境变量
django-admin.py startproject   项目名称

# 3. 项目文件目录
文件夹名称
manage.py       // 与Django进行交互命令的脚本
    // 全局文件
    项目名称
    wsgi.py         // 与socket有关
    settings.py     // 配置文件 包含了项目的一些设置,包括数据库信息、调试标志以及其他一些工作的变量
    urls.py         // 路径与视图函数的映射关系

# 4. 项目与应用
一个项目有多个应用;
一个应用可以被多个项目拥有;

# 5. 创建django应用
python manage.py startapp appname
appname
    models.py   // 与数据库交互文件
    views       //  存放视图函数

# 6. 启动django项目 
python3 manage.py runserver ip port

# 7. 迁移数据库
python manage.py makemigrations
python manage.py makemigrate

controller路由分配系统-URL

  1. 功能
    客户端访问的url的路径(path)和视图函数的一一映射关系;
  2. **语法格式*:
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
  1. 通过路径分组传参给视图函数
    必须在对应的视图函数设置形参接收。
    1. 无名分组
      加圆括号,视图函数增加对应的形参即可接受此路径:url(r‘^(\d{4})/‘, f1),, f1(request, year)
    2. 命名分组
      若路径中存在多个参数,那么可以采用命名分组:url(r‘^(?P<year>\d{4})/(?P<month>\d{2})‘, find1),
  2. url命名
    语法:
    url(r"^register/", register, name=‘register‘),
    前端<form action="{% url ‘register‘ %}" method="post">
    作用: 若url路径有所修改,在前端就不需要进行任何调整,模板语言会根据url命名来转换成最新的url;

  3. 路由应用分发
    对于项目下有多个应用的话,可以将每个应用的urls分开来: url(r"^blog", include("blog.urls"))
  4. 别忘记配置根目录
    url(r‘^$‘, views.index)

  5. 向server端传参数方式

# 1. 通过路径,分组参数:
    `<a href="localhost:8800/edit/1/"></a>`
    `url(r‘^edit/(\d+)/, views.f)`
    在view函数f中通过形参接收即可:`f(erquest, id)`;
# 2. 通过数据:域名/路径/?id=1, 通过reqeust.GET("id")可以取到id值;

视图函数-Views

// 两个对象:
请求对象: request
响应对象: Httpresponse("str")

// 两个请求方式
request.method: 请求方式;
request.GET: 存放get请求数据, 数据会放在path路径后,问号隔开,键值对
request.POST: 存放post数据;

// 两个方法
1. Httpresponse("str")    # 返回实例字符串对象;

2. render(request, "html")            # 模板渲染
   1. 读取html的内容,传入Httpresponse实例化即可;
   2. 渲染变量到html中:从后端取出数据,将数据键值对作为参数传入到html进行渲染;

        ```
        def show_time(request):
            import datetime
            time = datetime.datetime.now()
            return render(request, "time.html", {"time":time})
        ```
3. redirect(path)          # 跳转
    参数是url路径,随后调用对应的视图函数,与数据库交互取出变量,重新对html 进行渲染页面,并且跳转至目标路径下;
    **注意**: render不会直接修改当前的路径,仅仅渲染一个html页面,但是redirect会直接修改当前的路径;


// 模板语言语法:
    1. {{ }     // 渲染变量
    2. {% %}    // 渲染标签
// 模板语言目的: 将变量嵌入到html中;
// 注意:只要带有模板语法的html都成为模板;

模板-Template

定义: 模板就是html加上逻辑代码, 为了更好地渲染变量

标签语法

标签for循环语句
{% for person in person_list %}
    <p>{{person.name}}</p>
{% empty %)  // 判断是否为空,内置标签判断
    <p>没有符合的结果</p>
{%  endfor %}
标签if判断语句
{% if i > 100 %}
    <p>100</p>
{% else %}
    <p>{{i}}</p>
{% endif %}
{% with %}

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}
标签循环计数

当前循环计数{{forloop.counter}}


变量语法

内置过滤器

相当于模板的内置函数;
{{ 变量|filter:参数 }}

# 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值
<p>default过滤器:{{ li|default:"如果显示为空,设置的解释性的内容" }}</p>

# 返回值的长度。它对字符串和列表都起作用
{{ value|length }}

# 如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d" }}

# 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
<p>截断字符:{{ content|truncatechars:20 }}</p>
<p>截断单词:{{ content|truncatewords:4 }}</p>

# safe保证页面的安全性,将变量内容转换成纯文本
<p>{{ label }}</p>  <!--为了安全系统会把标签变成字符串-->
<p>{{ label|safe }}</p>    <!--加上safe,确定你的数据是安全的才能被当成是标签-->
value="<a href="">点击</a>"
{{ value|safe}}

自定义过滤器(标签和变量)

  1. 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
  2. 在app中创建templatetags模块(模块名只能是templatetags)
  3. 在templatetags里面创建任意 .py 文件
from django import template
register = template.Library()   #register的名字是固定的,不可改变

@register.filter   // 自定义过滤器, 只能传一个参数
def multi(x,y):
    return x*y

@register.simple_tag  // 自定义标签, 可以传多个参数
def multitag(x,y,z):
    return x*y*z
  1. 在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
    {% load my_tags %}

5、使用simple_tag和filter(如何调用)

-------------------------------.html
{% load xxx %}  
      
# num=12
{{ num|multi:2 }} #24
 
{{ num|multi:"[22,333,4444]" }}   相当于复制了,把[22,333,4444]乘了num遍
{% multitag 2 5 6 %} 参数不限,但不能放在if for语句中 {% simple_tag_multi num 5 %}

自定义过滤器函数的参数只能两个,可以进行逻辑判断
自定义标签无参数限制,不能进行逻辑判断

{% if i|multi:5 > 1000 %}   <!-- 判断i*5>1000 -->
    <p>大于{{ i }}</p>
{% else %}
    <p>大于等于{{ i }}</p>
{% endif %}
变量深度查询
# 方法1:
{{s.0}}             //对于views传入的有序集合s,在模板语法中直接可以通过索引取出来
{{d.属性名}}        //若传入的为键值对
{{obj_set.0.属性}}  // 若传入的为对象的集合,也可以取出相应的属性

# 方法2:
双下划线;

模板继承

  1. {% extends ‘base.html‘ %}必须放在首行;
  2. 覆盖父模板盒子中的内容:{% block name %} 重新定制的代码 {% endblock %}, 盒子越多越好,灵活性更好;
  3. 取到父模板盒子的内容,然后再对其追加内容:{{ block.super }};
  4. 不允许盒子重名

模型-model

# 若更改的model的属性,那么必须随之要重新运行数据库迁移命令;

数据库与ORM

对象关系映射
目的: 通过python的代码实现对数据库的增删改查;
在ORM中的对应关系:
表名 >>> 类名;
字段 >>> 类属性;
表的一条记录 >>> 类实例化对象

ORM之添加表记录

# 添加数据的两种方式
# 方式1:实例化对象就是一条表记录
Frank_obj = models.Student(name ="kate",course="python",birth="2000-9-9",score=80)
Frank_obj.save()

# 方式2:
models.Student.objects.create(name ="kate",course="python",birth="1995-5-9",score=88)

单表查询API

# 1、 all():查看所有
student_obj = models.Student.objects.all() // 打印的结果是QuerySet集合

# 2、filter():可以实现且关系,但是或关系需要借助Q查询实现, 查不到的时候不会报错
print(models.Student.objects.filter(name="Frank"))  #查看名字是Frank的
print(models.Student.objects.filter(name="Frank",score=80))  #查看名字是Frank的并且分数是80的

# 3、get():如果找不到就会报错,如果有多个值,也会报错,只能拿有一个值的
print(models.Student.objects.get(name="Frank"))  #拿到的是model对象
print(models.Student.objects.get(nid=2))  #拿到的是model对象

# 4、exclude():排除条件
print( models.Student.objects.exclude(name="kate")) #查看除了名字是kate的信息

# 5、values():是QuerySet的一个方法 (把对象转换成字典的形式了,)
print(models.Student.objects.filter(name="kate").values("nid","course")) #查看名字为kate的编号和课程
#打印结果:<QuerySet [{‘nid‘: 2, ‘course‘: ‘python‘}, {‘nid‘: 24, ‘course‘: ‘python‘}]>

# 6、values_list():是queryset的一个方法 (把对象转成元组的形式了)
print(models.Student.objects.filter(name="kate").values_list("nid", "course"))
#打印结果:< QuerySet[(2, ‘python‘), (24, ‘python‘)] >

# 7、order_by():排序,默认降序;
print(models.Student.objects.all().order_by("score"))

# 8、reverse():倒序, 先排序再反转;
print(models.Student.objects.all().reverse())

# 9、distinct():去重(只要结果里面有重复的)
print(models.Student.objects.filter(course="python").values("score").distinct())

# 10、count():查看有几条记录
print(models.Student.objects.filter(name="kate").count())

# 11、first()
# 12、last()
return render(request,"test.html",{"student_obj":student_obj})

# 13、esits:查看有没有记录,如果有返回True,没有返回False;并不需要判断所有的数据,
if models.Book.objects.all().exists():

双下划线之单表查询

# 获取id小于1 且 大于10的值
models.Tb1.objects.filter(id__lt=10, id__gt=1)

# 获取id等于11、22、33的数据
models.Tb1.objects.filter(id__in=[11, 22, 33])

# not in
models.Tb1.objects.exclude(id__in=[11, 22, 33])
 
# 名字包含ven的
models.Tb1.objects.filter(name__contains="ven")

# icontains大小写不敏感
models.Tb1.objects.filter(name__icontains="ven")
 
# 范围bettwen and
models.Tb1.objects.filter(id__range=[1, 2])
 
startswith,istartswith, endswith, iendswith

连表查询

基于对象的查询记录

修改

# 方法1
book = Book.objects.filter(id=id).first()
book.title=title
book.save()

# 方法2
Book.objects.filter(id=id).update(name=new_name)

查看数据库的sql语句(加在settings.py)

LOGGING = {
    ‘version‘: 1,
    ‘disable_existing_loggers‘: False,
    ‘handlers‘: {
        ‘console‘:{
            ‘level‘:‘DEBUG‘,
            ‘class‘:‘logging.StreamHandler‘,
        },
    },
    ‘loggers‘: {
        ‘django.db.backends‘: {
            ‘handlers‘: [‘console‘],
            ‘propagate‘: True,
            ‘level‘:‘DEBUG‘,
        },
    }
}

静态文件引入

1. 将所有静态文件放到一个static文件夹下;
2. 每个应用都应该有自己的静态文件夹;
3. `STATIC_URL = ‘/static/‘` 声明别名,`STATIC_ROOT = ( os.path.join(BASE_DIR, "bookSys/static") )`为实际路径, 只有用到别名那么都会到实际路径下寻找;
4. 在模板首行`{% load staticfiles %}`;
5. link rel="stylesheet" href={% static ‘css/bootstrap.css‘ %}";

以上是关于Django基础篇的主要内容,如果未能解决你的问题,请参考以下文章

02-Django-基础篇-Django介绍

Python自动化开发学习18-Django基础篇

01-Django-基础篇-Web框架简介

Django基础篇

django基础篇

如何在 Django Summernote 中显示编程片段的代码块?