栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django学习记录

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django学习记录

Django学习记录

注:此博客为仅为个人学习记录,会不断更新

Django应用及分布式路由 创建新的应用
  1. 创建方法:终端输入python manage.py startapp news,其中news是新的应用名

  2. 注册创建的APP,在项目的配置文件中(settings.py)找到INSTALLED_APPS列表,并在该列表中添加项目名,如下:

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'music',
        'sport',
        'news',
    ]
    

    最后的news即为新添加的应用

分布式路由

创建分布式路由的目的是为了让单个应用有单个应用的专属路由,不用一直在项目主路由中添加地址,正常的逻辑是创建了新的应用后,应该在项目主路由中为该应用配置专属的路由,而这个新建应用的路由则在自己的路由文件中去添加

  1. 在项目路由中添加新的应用路由地址,如下:

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('img', views.test_static),
        path('music/', include('music.urls')),
        path('sport/', include('sport.urls')),
        path('news/', include('news.urls')),
    ]
    

    列表的最后即为news应用的专属路由,而使用include方法,表明以后news的路由应该到news自己的urls.py文件中去添加

  2. 在新建应用下,创建一个urls.py来添加本应用的路由地址和对应的视图函数,如下:

    from django.urls import path
    from news import views
    
    urlpatterns = [
        path('index', views.index_view),
    ]
    

    index是news应用的地址,这种情况下,访问域名127.0.0.1:8000/news/index,浏览器返回的就是视图函数views中index_view方法所写的内容

模型层及ORM介绍

模型:

是Python的一个类,要求必须继承自django.db.models.Model, 一个模型类代表数据库中的一张数据表,模型类的每个熟悉代表数据库的一个字段,模型是数据增删改查的接口,用来操作数据库

ORM框架:

对象关系映射,允许使用类和对象对数据库进行操作,避免通过SQL语句操作数据库

终端进入MySQL

可以从cmd终端进入,也可以从编译器终端进入,指令都一样

mysql -uroot -p

接下来在终端输入密码

退出在终端输入quit即可

数据库模型文件

通过models.py生成数据表,如下

from django.db import models

# Create your models here.


class Book(models.Model):
    title = models.CharField("书名", max_length=50, default='')
    price = models.DecimalField("定价", max_digits=7, decimal_places=2, default=0.0)

通过上面这个文件,执行后应该会在数据库中生成一张Book数据表,这张表有两个字段,分别是title和price,但仅写完这个文件是不够的,需要在终端执行如下命名:

  1. 生成迁移文件,终端执行python manage.py makemigrations,将应用下的models.py文件生成一个中间件,并保存在migration文件夹中
  2. 执行迁移脚本程序,终端执行python manage.py migrate,将每个应用下的migration目录中的中间文件同步回数据库
ORM基础字段及选项 字段类型
  • BooleanField()布尔型
  • CharField()字符型
  • DateField()日期,参数:
    • auto_now:每次更新对象时,自动设置该字段为当前时间(取值True/False)
    • auto_now_add:对象第一次创建时自动设置当前时间(取值True/False)
    • default:设置当前时间
  • DateTimeField()日期时间,高频使用,比上面那个更频繁使用,基本创建表就会使用,一般会建两个字段,创建时间和修改时间,参数与DateField()相同
  • FloatField()浮点型
  • DecimalField()小数
  • EmailField(),数据库类型:varchar,Django封装好的
  • IntegerField()
  • ImageField()图片的存储路径,字符串
  • TextField() 类型longtext
  • ……
字段选项
  • 主键primary_key
  • blank,设置为True时,可以为空,设置为false时,字段必须填写
  • null,设置为True表示允许为空,默认为False
  • default,设置所在列的默认值,如果null=False建议添加此项
  • db_index,索引
  • unique, 唯一索引
  • db_column,指定字段名,一般不用给
  • verbose_name,admin上的显示名称
模型类Meta

使用内部类给模型赋予属性,比如修改表名

class Meta:
	db_table = 'book'
ORM基本操作-创建数据

models.Model模型类中的objects对象被继承,增删改查都是通过这个objects对象来实现

终端进入Django shell的命令:

python manage.py shell

第一种方法:

MyModel.models.Model.objects.create()

第二种方法:

创建模型对象实例,调用save()保存

obj = MyModel(attr1=value1, attr2=value2....)
obj.attr = value
obj.save()
ORM查询
  • objects.all() == select * from tabel,返回QuerySet容器对象,内部存放模型实例

    一般情况下,为了更好的显示查询结果,都要重新____str____函数,这是为了设置模型的返回值

    以下是查询示例

    from bookstore.models import Book
     al = Book.models.all()
    

    重写str函数

        def __str__(self):
            return '%s_%s_%s_%s' % (self.title, self.pub, self.price, self.market_price)
    

    查询结果

    , , , , ]>
    
  • objects.values(‘列1’, ‘列2’),查询部分列数据,返回QuerySet字典列表,等同于

    select lie1, lie2
    from Book
    
  • objects.values_list(‘列1’, ‘列2’),查询部分列数据,返回QuerySet元组列表

  • order_by()查询结果排序

ORM综合练习

目的:将数据库中,所有的book信息显示在all_book页面上,最终结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fD7K0o77-1651225916928)(C:UsersHPAppDataRoamingTyporatypora-user-imagesimage-20220429095725708.png)]

  1. 创建分布式路由:在主项目的urls.py文件中添加bookstore应用的路由,如下

    from django.contrib import admin
    from django.urls import path, include
    
    from mysite import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('img', views.test_static),
        path('music/', include('music.urls')),
        path('sport/', include('sport.urls')),
        path('news/', include('news.urls')),
        path('bookstore/', include('bookstore.urls')),
    ]
    

    最后一行即为bookstore应用的分布式路由

  2. 在bookstore应用中创建该应用的路由,在应用目录下新建一个urls.py,填入一下路由信息

    from django.urls import path
    
    from bookstore import views
    
    urlpatterns = [
        path('all_book', views.all_book),
    ]
    

    也就是当我访问http://127.0.0.1:8000/bookstore/all_book时指向的文件和视图函数

  3. 视图函数,在views.py文件中添加查询和渲染网页的代码

    from django.shortcuts import render
    from .models import Book
    
    
    # Create your views here.
    
    
    def all_book(request):
        all_book = Book.objects.all()
        return render(request, 'bookstore/all_book.html', locals())
    
    

    使用all()方法查询到所有的数据,并把查到的all_book传递给模板文件夹(templates)下bookstore文件夹中的all_book.html文件,locals()函数将查询到的局部变量转换成字典数据,也就是把all_book转换成字典,讲真,我真没理解这个locals到底怎么用的

  4. 模板文件,在模板中填写网页展示的内容,并接受视图函数传递过来的数据,并进行展示

    
    
    
        
        查看所有表格
        
    
    
    
        {% for book in all_book %}
            
    
        {% endfor %}
        
    id title pub price market_price op
    {{ book.id }} {{ book.title }} {{ book.pub }} {{ book.price }} {{ book.market_price }} 更新 删除

    这里关键是要理解那一段for循环的写法

    不写CSS样式显示出来的表格很丑,没有边框,我在样式中改了一下边框,在两个地方

小结1

其实写到这里,Django的作用和整个操作流程,已经大致显示出来了,有必要做个小结:

  1. 首先启动一个Django项目——mysite
  2. 在Django项目中新建一个应用——bookstore
  3. 为项目(mysite)创建分布式路由,在路由中添加bookstore的分布式路由
  4. 在应用(bookstore)中添加路由,指定地址指向的视图函数
  5. 在应用的视图函数中添加方法,如果需要向数据库传递数据,就要启动数据库模型
    1. 在应用的model.py文件中添加模型,注意,一个模型就是一张表,可以在这个表中进行增删改查操作
    2. 如果有必要,重写一下默认的str方法
    3. 视图函数中对模型数据进行处理,可以查询、排序等操作,并返回查询的值
  6. 在应用中创建模板文件(html文件),需要在应用下新建一个templates文件夹,最好是在templates文件夹下再创建一个与应用同名的文件夹(防止路由找不到模板文件)用来存放模板文件,在模板文件下编写页面文件,并接收视图函数传递过来的数据,使用Django特有的语法处理接收到的数据并写入到模板文件中
  7. 启动项目,访问地址,即可展示页面
条件查询 普通查询
  • filter()方法,返回QuerySet

    MyModel.objects.filter(attr1=value1, attr2=valur2…)

    多个属性在一起时为“与”关系

  • exclude(条件),不包含此条件的数据集

  • get(条件),返回单条数据,如果给定的条件超过一条,或者没有数据,都会报错

查询谓词

查询示例:

Book.objects.filter(id__exact=1)

等同于

select * from Book where id = 1

由字段名__谓词组成

  • __exact等值匹配,经常用来匹配是否为空,is null
  • __contains包含指定值查询,**经常使用,**类似于sql中的like ‘%xxx%’
  • __startwith以XXX开始
  • __endwith以XXX结尾
  • __gt大于指定值,常用
  • __gte大于等于指定值,常用
  • __lt小于指定值,常用
  • __lte小于等于指定值,常用
  • __in查找的数据是否在指定范围内,常用,示例Book.objects.filter(id__in = [1,3,5])
  • __range指定区间范围内查询,和sql中的between一样,常用,示例Book.objects.filter(id__range = (20,40))
  • 还有很多…
ORM更新操作

流程:查(使用get)->改->存(使用save)

后端更改操作

单条数据更新的具体示例:

# 单条数据更新
b1 = Book.objects.get(id=1)
b1.price = 22
b1.save()

批量更新,直接将查询结果使用update方法更新

# 批量更新
b1 = Book.objects.filter(price__gt=50)
b1.update(market_price=100)

将所有定价大于50的书市场价均设置为100

通过前端超链接页面更新

前面的图书管理界面上,最后一列“op”绑定了两个空链接,现在先来实现更新功能

一步步来

添加视图函数

views.py中添加的内容

def update_book(request, book_id):
    try:
        book = Book.objects.get(id=book_id)
    except Exception as e:
        print('--update book error is %s' % (e))
        return HttpResponse("书本不存在")
    if request.method == 'GET':
        return render(request, 'bookstore/update_book.html', locals())
    elif request.method == 'POST':
        price = request.POST['price']
        market_price = request.POST['market_price']
        book.price = price
        book.market_price = market_price
        book.save()
        return HttpResponseRedirect('/bookstore/all_book')

这个视图函数还挺复杂的,记录一下逻辑

既然是要更改数据,就说明要像数据库传递数据,那么一般是post请求,但是超链接是get请求,所以实际上要对请求进行判断

  1. 首先,如果是get请求,就跳转到路由指定的模板文件上,并通过local()将get到的局部变量打包成字典,传递给模板文件update_html,模板文件见下面小节(添加模板文件)

  2. 如果是post请求,也就是说要通过页面给后台传递参数了,那么把要实现的功能在这里写好,也就是在这里实现数据的更新

    1. 查数据

    2. 改数据

    3. 存数据

    4. 返回HttpResponse实体,代码中是重定向,指定了路由的相对路径,绝对路径应该是http://127.0.0.1:8000/bookstore/all_book

      强调一下,这里的return必须写,至于是render、HttpResponse还是HttpResponseRedirect根据业务需求,不然项目不知道下一步该往哪里去

  3. 逻辑上已经没什么问题,但有一点要注意,查询book是用的get方法,get方法具有唯一性,极易报错,所以有必要进行异常检测

  4. 视图函数中我传递了一个book_id参数,这点非常重要。首先这个参数是我们要查询的书名,其次,路由中也要用到,下面会讲到

添加模板文件

视图函数完成后,就要进行前端页面的设计了,前面的逻辑是点击超链接(get请求)的话,就去渲染网页文件,并向网页传递book参数

update_html里的内容




    
    更改书籍


title

publish

price

market_price

看看界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YoKmMgAy-1651225916930)(C:UsersHPAppDataRoamingTyporatypora-user-imagesimage-20220429142029973.png)]

界面还有待优化,这是CSS的事情,暂时不进行美化

很明显是表单数据,因此使用form标签,form的action参数是表单数据请求指向的地址,也就是路由,这个路由的写法也是用的Django语法

注意get请求向这个网页文件传递了book参数,也就是通过book_id获取到的book信息,因此book.id就是数据库中的id字段,title,pub等等也是,4个input标签中各填入了book的4个参数,通过value匹配,用的也是Django的语法,其中title,pub是不可修改的(“disabled” )

最后一个input标签是提交按钮,也就是点击后发送post请求到数据库,并重定向到视图函数中写好的地址

添加路由

目前数据库中是有5本书的,也就是说,如果按绝对路径来定义路由的话,要定义5个路由,分别是

path('update_book/1', views.update_book),
path('update_book/2', views.update_book),
path('update_book/3', views.update_book),
path('update_book/4', views.update_book),
path('update_book/5', views.update_book),

这么写明显不合理,如果有100个,是不是要写100行

这里有多种替代方式

  • 通过正则表达式来传递
  • 通过Django的path转换器来传递

这里使用的是path转换器,用path转换器记得在视图函数中传递参数,这点非常重要,前面就已经提到了,视图函数中传递了一个book_id这个参数,视图函数通过这个book_id进行了一系列的操作,使用path路由的时候也要用到,正确的写法如下

urls.py中的内容

from django.urls import path

from bookstore import views

urlpatterns = [
    path('all_book', views.all_book),
    path('update_book/', views.update_book),
]

添加了一个path('update_book/', views.update_book)

path转换器的精髓就在这里,接收视图函数传递的形参,使用<>来转换,前面是这个数据的类型,后面是参数,有点像java中的泛型

小结2

这里算是完成了一个相对初学者来说,比较复杂的功能,涉及到的技术栈有:

  1. 数据库的更新,包括查-改-存
  2. 视图函数的创建,包括两种不同的请求,重定向等
  3. 如何像模板文件传递参数
  4. 如何通过path转换器指定路由

参数,视图函数通过这个book_id进行了一系列的操作,使用path路由的时候也要用到,正确的写法如下

urls.py中的内容

from django.urls import path

from bookstore import views

urlpatterns = [
    path('all_book', views.all_book),
    path('update_book/', views.update_book),
]

添加了一个path('update_book/', views.update_book)

path转换器的精髓就在这里,接收视图函数传递的形参,使用<>来转换,前面是这个数据的类型,后面是参数,有点像java中的泛型

小结2

这里算是完成了一个相对初学者来说,比较复杂的功能,涉及到的技术栈有:

  1. 数据库的更新,包括查-改-存
  2. 视图函数的创建,包括两种不同的请求,重定向等
  3. 如何像模板文件传递参数
  4. 如何通过path转换器指定路由
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/844141.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号