Django模型基础(ORM、字段类型、字段参数、增删改查和分页)

news2024/11/20 9:26:19

模型基础:

字段类型:

django根据属性的类型确定以下信息

  • 当前选择的数据库⽀持字段的类型
  • 渲染管理表单时使⽤的默认html控件
  • 在管理站点最低限度的验证
  • django会为表增加⾃动增⻓的主键列,每个模型只能有⼀个主键列,如果使⽤选项设置某属性为主键列后,则django不会再⽣成默认的主键列。

属性命名限制

·遵循标识符规则
·由于django的查询⽅式,不允许使⽤连续的下划线
定义属性时,需要字段类型,字段类型被定义在django.db.models.fields⽬录下,为了⽅便使⽤,被导⼊到django.db.models中

使⽤⽅式

  • 导⼊from django.db import models
  • 通过models.Field创建字段类型的对象,赋值给属性

逻辑删除和物理删除

​ 对于重要数据都做逻辑删除,不做物理删除,实现⽅法是定义is_delete属性,类型为BooleanField,默认值为False。(物理删除就是真正对数据库进行操作,逻辑删除就是打标记,筛选一下就可以)。

is_delete = models.BooleanField(default=False)

常⽤字段类型:

  • AutoField
    ·⼀个根据实际ID⾃动增⻓的IntegerField,通常不指定, 如果不指定,主键字段id将⾃动添加到模型中。

  • CharField(max_length=字符⻓度)
    ·字符串,默认的表单样式是 Input,相当于数据库中的varchar.

  • TextField
    ·⼤⽂本字段,⼀般超过4000使⽤,默认的表单控件是Textarea,相当于数据库中的text.

  • IntegerField
    ·整数

  • DecimalField(max_digits=None, decimal_places=None)
    ·使⽤python的Decimal实例表示的⼗进制浮点数
    ·参数说明
    ·DecimalField.max_digits
    ·位数总数
    ·DecimalField.decimal_places
    ·⼩数点后的数字位数

  • FloatField

​ ⽤Python的float实例来表示的浮点数

  • BooleanField

​ True/False 字段,此字段的默认表单控制是CheckboxInput

  • DateField([auto_now=False, auto_now_add=False])

​ ·使⽤Python的datetime.date实例表示的⽇期

​ ·参数说明

​ ·DateField.auto_now

​ 每次保存对象时,⾃动设置该字段为当前时间,⽤于"最后⼀次修改"的时间戳,它总是使⽤当前⽇期,默认为false。

DateField.auto_now_add

当对象第⼀次被创建时⾃动设置当前时间,⽤于创建的时间戳,它总是使⽤创建时的⽇期,默认为false。

​ 注意:auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发⽣错误的结果

  • TimeField

​ 使⽤Python的datetime.time实例表示的时间,参数同DateField。

  • DateTimeField

·使⽤Python的datetime.datetime实例表示的⽇期和时间,参数同DateField。

  • FileField

    ⼀个上传⽂件的字段

  • ImageField

继承了FileField的所有属性和⽅法,但对上传的对象进⾏校验,确保它是个有效的image

需要安装Pillow: “pip install Pillow”

字段参数:

字段参数写在models.BooleanField()内部。

# 常⽤字段选项(通过字段选项,可以实现对字段的约束):
1、 null=True
数据库中字段是否可以为空
2、 blank=True
django的 Admin 中添加数据时是否可允许空值

⼀般null=True & blank=True 搭配着⽤,出现null=True就⽤上blank=True
3、 primary_key = True
主键,对AutoField设置主键后,就会代替原来的⾃增 id 列
4、 auto_now 和 auto_now_add
auto_now	⾃动创建---⽆论添加或修改,都是当前操作的时间
auto_now_add ⾃动创建---永远是创建时的时间

5、 choices (后台admin下拉菜单)
//限制选择
USER_TYPE_LIST = (
(1, '超级⽤户'),
(2, '普通⽤户'),)

user_type = models.IntegerField(choices=USER_TYPE_LIST,
default=1, verbose_name='⽤户类型')
6、 max_length 最⼤⻓度
7、 default	默认值
8、 verbose_name	Admin(后台显示的名称)中字段的显示名称(类似注释)
9、 name|db_column		数据库中的字段名称
10、unique=True	不允许重复
11、db_index = True	数据库索引,例如:如果你想通过name查询的更快的话,给他设置为索引即可
12、editable=True 在Admin⾥是否可编辑,不可编辑则不显示
13、设置表名
class Meta:
	db_table = 'person' (表名)

案例实战:

创建项目工程:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

数据迁移:

python manage.py makemigrations

映射数据库:

python manage.py migrate

在这里插入图片描述

注意:每对模型进行一次修改,都需要重新进行映射。

对于新添加的列,最后给一个默认值,因为可能前几列的值已经固定了,但是我们后面的列没有进行赋值,就会存在问题.

在这里插入图片描述

后台管理配置:

在这里插入图片描述

设置管理员:

python manage.py createsuperuser

在这里插入图片描述

后台查看:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

显示问题:

如果想让其显示除需要定义model的魔术方法例如:

    def __str__(self): # 控制
        return f'{self.id}-{self.name}-{self.age}'

    def __repr__(self):
        return f'{self.id}-{self.name}-{self.age}'

在这里插入图片描述

如何实现回滚操作呢?

1.首先删除migrantions中的内容,如下:

在这里插入图片描述

  1. 在数据库中删除

在这里插入图片描述

App下的models.py

from django.db import models


# 模型 字段类型和约束
class UserModel(models.Model):
    # uid 会成为主键,原来的id不会创建
    uid = models.AutoField(auto_created=True, primary_key=True)
    # CharField: 字符串类型,unique唯一,db_index索引
    # 名字唯一
    name = models.CharField(max_length=30, unique=True, db_index=True)
    # IntegerField: 整数类型,default默认值
    age = models.IntegerField(default=18)
    # BooleanField: bool类型
    sex = models.BooleanField(default=True)

    # # TextField:长字符串,大文本,
    #       null=True 表示可以为空,blank=True在Admin管理页面可以为空,一般都是同时写
    info = models.TextField(null=True, blank=True)
    # # FloatField: 小数
    salary = models.FloatField(default=100000.345)

    # DecimalField: 十进制小数,
    #     max_digits=4:最大长度
    #     decimal_places=2:小数点后是2位
    money = models.DecimalField(max_digits=4, decimal_places=2, default=10.34)

    # # 日期
    birthday = models.DateField(default='2000-03-04')

    birthday2 = models.DateTimeField(auto_now=True)  # 每一次修改后都会自动修改该时间为最新的修改时间
    birthday3 = models.DateTimeField(auto_now_add=True)  # 第一次添加数据的时候的时间,以后不会再修改
    birthday4 = models.DateTimeField(auto_now_add=True)  # 第一次添加数据的时候的时间,以后不会再修改

    # # 文件和图片
    # 保存图片的二进制  可以为空
    icon = models.FileField(null=True, blank=True, upload_to='static/uploads')
    icon2 = models.ImageField(null=True, blank=True, upload_to='static/uploads')

    #
    # # 其他约束
    # 元组中第一个参数是我们输入的元素
    # name 属性表示在数据库中生成的字段名字
    # db_column 数据库中的字段名称
    # verbose_name 是在后台管理系统中显示出来的名字
    # editable=True 在Admin⾥是否可编辑,不可编辑则不显示
    choices = ((1, '青铜'), (2, '大师'), (3, '王者'))
    user_type = models.IntegerField(choices=choices, default=1,
                                    name='utype', verbose_name='用户类型')
    user_type2 = models.IntegerField(default=1,  editable=False,
                                     db_column='utype2', verbose_name='用户类型2')

    def __str__(self):
        return f'{self.name} - {self.age}'


在这里插入图片描述

在这里插入图片描述

模型操作:

⼀般的数据库操作流程:

  1. 创建数据库,设计表结构和字段
  2. 连接Mysql数据库,并编写数据访问层代码
  3. 业务逻辑层去调⽤数据访问层执⾏数据库操作

​ Django通过Model操作数据库,不管你数据库的类型是MySql或者Sqlite,Django⾃动帮你⽣成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Django帮我们⾃动完成。只要会写Model就可以了。

​ django使⽤对象关系映射(Object Relational Mapping,简称ORM)框架去操控数据库。

​ ORM(Object Relational Mapping)对象关系映射,是⼀种程序技术,⽤于实现⾯向对象编程语⾔⾥不同类型系统的数据之间的转换。

ORM:

模型<=>
类结构->表结构
对象->表的⼀条数据
类属性->表的字段

增删改查:

添加:
# models基本操作
# 增:
1)创建对象实例,然后调⽤save⽅法:
    obj = Author()
    obj.first_name = 'zhang'
    obj.last_name = 'san'
    obj.save()      
2)创建对象并初始化,再调⽤save⽅法:
	obj = Author(first_name='zhang', last_name='san') obj.save()
3)使⽤create⽅法
	Author.objects.create(first_name='li', last_name='si') 
4)使⽤get_or_create⽅法,可以防⽌重复
	Author.objects.get_or_create(first_name='zhang', last_name='san')

class PersonModel(models.Model):
    name = models.CharField(max_length=30, unique=True)
    age = models.IntegerField(default=18)

    class Meta:
        # 自定义表名(默认是app的名字+模型名的小写)
        db_table = 'tb_person'

    def __str__(self):
        return f'{self.id}-{self.name}-{self.age}'

    def __repr__(self):
        return f'{self.id}-{self.name}-{self.age}'

迁移:

在这里插入图片描述

查看表结构:

在这里插入图片描述

App下的views.py 提供接口

import math

from django.db.models import Max, Min, Sum, Avg, Count
from django.shortcuts import render, HttpResponse

# 导入models
from App.models import *


# 增加数据
def add_person(request):
    # 方式1
    # try:
    #     p = PersonModel()
    #     p.name = '李四'
    #     p.age = 44
    #     p.save()  # 同步到数据库表中
    # except Exception as e:
    #     return HttpResponse('添加失败')
    #
    # return HttpResponse('添加成功!')

    # 方式2
    # try:
    #     p = PersonModel(name='王五', age=55)
    #     p.save()  # 同步到数据库表中
    # except Exception as e:
    #     return HttpResponse('添加失败')
    #
    # return HttpResponse('添加成功!')

    # 方式3
    # try:
    #     PersonModel.objects.create(name='赵六', age=66)
    # except Exception as e:
    #     return HttpResponse('添加失败')
    #
    # return HttpResponse('添加成功!')

    # 方式4
    # try:
    #     ret = PersonModel.objects.get_or_create(name='钱七', age=77)
    #     print('ret:', ret)
    #     # ret: (<PersonModel: PersonModel object (5)>, True)
    #     # 如果是第一次创建:则是True,如果已经存在则是False
    #
    # except Exception as e:
    #     return HttpResponse('添加失败')



    # 添加多条数据
    for i in range(21, 51):
        PersonModel.objects.create(name=f'武{i}范', age=i)

    return HttpResponse('添加成功!')

项目工程下的urls.py 写路由

在这里插入图片描述

from django.contrib import admin
from django.urls import path

from App.views import *

urlpatterns = [

    path('add/', add_person),  # 添加数据
    # path('del/', del_person),  # 删除数据
    # path('update/', update_person),  # 修改数据
    # path('get/', get_person),  # 查询数据
    #
    # # 分页
    # path('paginate/<int:page>/', paginate, name='paginate'),
    # path('paginate2/<int:page>/', paginate2, name='paginate2'),

    path('admin/', admin.site.urls),
]

在这里插入图片描述

在这里插入图片描述

删除:
# 删:
	使⽤Queryset的delete⽅法:
# 删除指定条件的数据
    Author.objects.filter(first_name='zhang').delete() # 删除所有数据
    Author.objects.all().delete()
    注意: objects不能直接调⽤delete⽅法。
    使⽤模型对象的delete⽅法:
    obj = Author.objects.get(id=5) obj.delete()

views.py

# 删除数据
def del_person(request):
    # 删除数据:
    #  1. 先找到要删除的数据
    #  2. 然后删除
    try:
        # 删除一条数据
        # p = PersonModel.objects.first()  # 第一条数据
        # p.delete()

        # 删除多条数据
        PersonModel.objects.filter(age__gt=15).delete()  # age>15的多条数据

    except Exception as e:
        return HttpResponse('删除失败!')

    return HttpResponse('删除成功!')

在这里插入图片描述

修改:
# 改:
	Author.objects.filter(last_name='dfdf').update(last_name='san')
模型没有定义update⽅法,直接给字段赋值,并调⽤save,能实现update的功能,⽐如:
	obj = Author.objects.get(id=3) 
	obj.first_name = 'zhang' 
	obj.save()
save更新时会更新所有字段。如果只想更新某个字段,减少数据库操作,可以这么做:
    obj.first_name = 'li'
    obj.save(update_fields=['first_name'])

views.py

# 修改数据
def update_person(request):
    # 修改数据
    #  1. 先找到要修改的数据
    #  2. 然后修改
    try:
        # 修改一条数据
        p = PersonModel.objects.first()
        p.age = 666
        # p.save()  # 同步到数据库表中
        p.save(update_fields=['age'])  # 指定更新的字段,提高更新效率

        # 修改多条数据
        # PersonModel.objects.all().update(age=100)

    except Exception as e:
        return HttpResponse('修改失败!')

    return HttpResponse('修改成功!')

在这里插入图片描述

在这里插入图片描述

查询:
# 查:
get():获取单条数据:
	Author.objects.get(id=123)  # 一般对主键或者唯一的
	如果没有找到符合条件的对象,会引发模型类.DoesNotExist异常如果找到多个,会引发模型类.MultipleObjectsReturned 异常
first():返回查询集(QuerySet)中的第⼀个对象   
last():返回查询集中的最后⼀个对象         
count():返回当前查询集中的对象个数         
exists():判断查询集中是否有数据,如果有数据返回True没有反之 
all():获取全部数据集:
	Author.objects.all()
values(): 获取指定列的值,可以传多个参数!返回包含字典的列表(保存了字段名和对应的值)
	Author.objects.all().values('password')
values_list(): 获取指定列的值,可以传多个参数!返回包含元组列表(只保存值)
	Author.objects.all().values_list('password')

进阶操作:
# 获取个数
Author.objects.filter(name='seven').count()

Author.objects.filter(id gt=1)	# 获取id⼤于1的值
# select * from Author where id > 1

Author.objects.filter(id gte=1)	# 获取id⼤于或等于1的值
# select * from Author where id >= 1

Author.objects.filter(id lt=10)	# 获取id⼩于10的值
# select * from Author where id < 10

Author.objects.filter(id lte=10)	# 获取id⼩于或等于10的值
# select * from Author where id <= 10

Author.objects.filter(id lt=10, id gt=1)	# 获取id⼤于1 且 ⼩于10的值
# select * from Author where id < 10 and id > 1

Author.objects.filter(id in=[11, 22, 33])	# 获取id在11、22、33中的数据
# select * from Author where id in (11,22,33)

# exclude 除了以外,取反
Author.objects.exclude(id in=[11, 22, 33]) # not in # select * from Author where id not in (11,22,33)

Author.objects.filter(name contains="ven") # contains(和数据库中like语法相同) # select * from Author where name like '%ven%'
Author.objects.filter(name icontains="ven") # icontains⼤⼩写不敏感
Author.objects.filter(name regex="^ven") # 正则匹配
Author.objects.filter(name iregex="^ven") # 正则匹配,忽略⼤⼩写
Author.objects.filter(age range=[10, 20])	# 范围bettwen and

# startswith,istartswith, endswith, iendswith:
# 以什么开始,以什么结束,和上⾯⼀样带i的是⼤⼩写不敏感的, 其实不带i的也忽略⼤⼩写

Author.objects.filter(name='seven').order_by('id')	# asc升序 Author.objects.filter(name='seven').order_by('-id')	# desc降序
Author.objects.all()[10:20] # 切⽚,取所有数据的10条到20条,分⻚的时候⽤的到,
# 下标从0开始,不能为负数, 可以实现分⻚

views.py

# 查询数据
def get_person(request):

    # get(): 得到一个对象(一条数据) 必须获得一条数据
    #        如果没有找到符合条件的对象,会引发模型类.DoesNotExist异常
    # 	     如果找到多个,会引发模型类.MultipleObjectsReturned 异常
    p = PersonModel.objects.get(id=5)
    # p = PersonModel.objects.get(18)  # 不可以这样写,会报错

    # p = PersonModel.objects.get(pk=6)  # pk:primary key
    # p = PersonModel.objects.get(age=100)  # 可以
    # p = PersonModel.objects.get(age=100)  # 不可以,报错,MultipleObjectsReturned
    # # p = PersonModel.objects.get(age=1000)  # 不可以,报错,DoesNotExist
    # print('*' * 30)
    # print(p, type(p))  # PersonModel对象
    # print(p.name, p.age)
    # print('*' * 30)

#     # all(): 获取所有数据
    # <QuerySet [5-武21范-100, 6-武22范-100, 7-武23范-100, 8-武24范-100, 9-武25范-100, 35-de-100]>
    persons = PersonModel.objects.all()
    print(persons, type(persons))
#     # QuerySet 查询集
#     # 可以遍历查询集
    for p in persons:
        print(p.name, p.age)
#
#     # first(): 第一条数据
    p = PersonModel.objects.first()
    print(p.name, p.age)
#
#     # last(): 最后一条数据
    p = PersonModel.objects.last()
    print(p.name, p.age)
    return HttpResponse('查询成功!')

在这里插入图片描述

过滤filter:

#     # filter(): 过滤,使用最多
#     查询有可能一条  也有可能多条,所以得到的是查询集
#     persons = PersonModel.objects.filter()  # 默认没有条件,得到所有数据
    persons = PersonModel.objects.filter(age__gt=300)  # age>300
    persons = PersonModel.objects.filter(age__gte=300)  # age>=300
    persons = PersonModel.objects.filter(age__lt=300)  # age<300
    persons = PersonModel.objects.filter(age__lte=300)  # age<=300
    persons = PersonModel.objects.filter(age=300)  # age=300

#     # 查询集可以做链式调用  相当于子查询
#     print(persons.filter().filter().all().first())
    print(type(persons))  # django.db.models.query.QuerySet
#     for p in persons:
#         print('--- ', p.name, p.age)
# #
#     print(persons.first())
#     print(persons.last())
#     print(persons.exists())  # 查询集是否存在数据,如果存在则为True,否则为False
#     print(persons.count())  # 查询集中的数据个数

    # values() 和 values_list()
    persons = PersonModel.objects.filter().all()
    print("persons:", persons)
    print("list(persons):", list(persons))  # 将查询集强制转换成列表

    # values() : 列表套字典,包括字段和值
    #  <QuerySet [{'name': '武21范', 'age': 100}, {'name': '武22范', 'age': 50}, {'name': '武23范', 'age': 300
    # }, {'name': '武24范', 'age': 100}>
    print("persons.values():", persons.values())  # 列表套字典
    # 指定某个字段
    print("persons.values('name', 'age'):", persons.values('name', 'age'))

    # values_list():  列表套元组, 只有值
    # <QuerySet [(5, '武21范', 100), (6, '武22范', 50), (7, '武23范', 300), (8, '武24范', 100), (9, '武25范', 200), (
    # 35, 'de', 600)]>
    print("persons.values_list():", persons.values_list())
    print("persons.values_list('name', 'age'):", persons.values_list('name', 'age'))
    
    # 包含 正则 in
    print('-' * 60)
    # filter(): 详细, 类似数据库中的where语句
    persons = PersonModel.objects.filter(age__in=[100, 200, 666, 777, 888])  # in
    # exclude(): 排除,取反的意思

    persons = PersonModel.objects.exclude(age__in=[100, 200, 666, 777, 888])  # not in
    persons = PersonModel.objects.filter(age__contains='6')  # 包含, 模糊查找,类似like
    persons = PersonModel.objects.filter(name__contains='3')  # 包含, 模糊查找,类似like
    persons = PersonModel.objects.filter(name__icontains='3')  # 包含, 模糊查找,类似like ignore大小写(忽略大小写)
    persons = PersonModel.objects.filter(name__regex='^wu')  # 正则匹配,姓武的
    persons = PersonModel.objects.filter(name__iregex='^wu')  # 正则匹配,忽略大小写
    persons = PersonModel.objects.filter(age__range=[200, 400])  # 200-400之间,两边都包含

    # 开头和结尾 
    persons = PersonModel.objects.filter(name__startswith='wu')  # 以wu开头,忽略大小写
    persons = PersonModel.objects.filter(name__istartswith='wu')  # 以wu开头,忽略大小写
    persons = PersonModel.objects.filter(name__endswith='wu')  # 以wu结尾,忽略大小写
    persons = PersonModel.objects.filter(name__iendswith='wu')  # 以wu结尾,忽略大小写
    print(persons)

聚合函数:

#     # 聚合函数:max,min,sum
    # 返回的是字典 {'age__max': 600}
    result = PersonModel.objects.aggregate(Max('age'))  # 最大值  {'age__max': 666}
    result = PersonModel.objects.aggregate(Min('age'))  # 最小值  {'age__min': 100}
    result = PersonModel.objects.aggregate(Sum('age'))  # 求和  {'age__sum': 1666}
    result = PersonModel.objects.aggregate(Avg('age'))  # 平均值  {'age__avg': 333.2}
    result = PersonModel.objects.aggregate(Count('age'))  # 计数  {'age__count': 5}
    print(result)

排序:

    # 排序
    # 默认是按照升序排列 
    # -字段 表示降序
    persons = PersonModel.objects.all().order_by('age')  # 升序
    persons = PersonModel.objects.all().order_by('age', '-id')  # 先按照age升序,如果age相同则按id降序排列
    persons = PersonModel.objects.all().order_by('-age')  # 降序
    print(persons)
分页:

手动分页:

views.py

# 分页功能
# 手动分页
def paginate(request, page=1):
    # 页码:page
    # 每页数量:per_page
    per_page = 10

    # 分页功能:
    #  数据 =【1,2,3,4,5,...,100】
    #   第几页       数据范围       数据下标范围      切片
    #   page=1        1 ~ 10      0 ~ 9        [0 : 10]
    #   page=2       11 ~ 20     10 ~ 19       [10 : 20]
    #   page=3       21 ~ 30     20 ~ 29       [20 : 30]
    #   page=4       31 ~ 40     30 ~ 39       [30 : 40]
    #   ...
    #   page=n                        [(n-1) * 10  :  n * 10]
    #   page=page                     [(page-1) * per_page  :  page * per_page]

    # 实现分页功能
    persons = PersonModel.objects.all()
    persons = persons[(page-1) * per_page  :  page * per_page] # 切片

    # 总页数
    total = PersonModel.objects.count()  # 总数据量
    total_page = math.ceil(total / per_page)  # 总页数 向上取整,因为可能有一部分不到10个
    pages = range(1, total_page+1)  # 1,2,3,4,5,6,7...

    data = {'persons': persons,'pages': pages}
    return render(request, 'paginate.html', data)

templates下的paginate.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        ul {list-style: none; padding: 0}
        .btns li {
            float: left;
            margin: 5px;
        }
        hr {
            clear: both;
        }
    </style>
</head>
<body>
    <h2>分页功能</h2>
    <hr>

    <ul class="btns">
        {% for page in pages %}
            <li>
                <a href="{% url 'paginate' page %}"> <button>{{ page }}</button> </a>
            </li>
        {% endfor %}


    </ul>

    <hr>
    <ul>
        {% for person in persons %}
            <li>{{ person.name }} - {{ person.age }}</li>
        {% endfor %}
    </ul>


</body>
</html>

当然了,还有进行路由绑定:

在这里插入图片描述

在这里插入图片描述

自动分页:

在这里插入图片描述

# 分页器:自动分页
from django.core.paginator import Paginator


def paginate2(request, page=1):
    per_page = 10 # 每一页数量

    all_data = PersonModel.objects.all()

    # 分页器
    paginator = Paginator(all_data, per_page)
    persons = paginator.page(page)  # 获取第page页的数据
    pages = paginator.page_range  # 页码范围,可以遍历

    data = {'persons': persons, 'pages': pages}
    return render(request, 'paginate2.html', data)

在这里插入图片描述

from django.contrib import admin
from django.urls import path

from App.views import *

urlpatterns = [

    path('add/', add_person),  # 添加数据
    path('del/', del_person),  # 删除数据
    path('update/', update_person),  # 修改数据
    path('get/', get_person),  # 查询数据
    #
    # 分页
    path('paginate/<int:page>/', paginate, name='paginate'), # 给这个路由函数起一个名字
    path('paginate2/<int:page>/', paginate2, name='paginate2'),

    path('admin/', admin.site.urls),
]

templates下的paginate2.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        ul {list-style: none; padding: 0}
        .btns li {
            float: left;
            margin: 5px;
        }
        hr {
            clear: both;
        }
    </style>
</head>
<body>
    <h2>分页功能</h2>
    <hr>

    <ul class="btns">

        {% for page in pages %}
            <li>
                <a href="{% url 'paginate2' page %}"> <button>{{ page }}</button> </a>
            </li>
        {% endfor %}

    </ul>

    <hr>
    <ul>
        {% for person in persons %}
            <li>{{ person.name }} - {{ person.age }}</li>
        {% endfor %}
    </ul>


</body>
</html>

总结

本篇博客深入探讨了Django中的模型基础,涵盖了ORM(对象关系映射)的概念及其在Django中的应用,详细介绍了各种字段类型以及常用字段参数的使用方法。通过实战案例的讲解,读者将学习如何在Django中使用模型进行数据操作,并解答了一些常见问题。此外,我们还重点介绍了模型的基本操作,包括CURD(创建、读取、更新和删除)以及分页的实现方法。无论您是初学者还是有一定经验的开发者,本文都将为您提供全面而实用的Django模型知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习 LangChain 的 LCEL

学习 LangChain 的 LCEL 0. 引言1. 基本示例&#xff1a;提示模型输出解析器​1-1. Prompt​1-2. Model1-3. Output parser1-4. Entire Pipeline 0. 引言 LCEL(LangChain Expression Language) 可以轻松地从基本组件构建复杂的链&#xff0c;并支持开箱即用的功能&#xff0c;…

掌握BeautifulSoup4:爬虫解析器的基础与实战【第91篇—BeautifulSoup4】

掌握BeautifulSoup4&#xff1a;爬虫解析器的基础与实战 网络上的信息浩如烟海&#xff0c;而爬虫技术正是帮助我们从中获取有用信息的重要工具。在爬虫过程中&#xff0c;解析HTML页面是一个关键步骤&#xff0c;而BeautifulSoup4正是一款功能强大的解析器&#xff0c;能够轻…

mongoose httpserver浅析

文章目录 前言一、结构体及其功能二、函数MG_LOGmg_http_listenmg_mgr_poll question参考链接 前言 mongoose是一款基于C/C的网络库&#xff0c;可以实现TCP, UDP, HTTP, WebSocket, MQTT通讯。mongoose是的嵌入式网络程序更快、健壮&#xff0c;易于实现。 mongoose只有mong…

云尚办公-0.0.1

1. 核心技术 基础框架&#xff1a;SpringBoot数据缓存&#xff1a;Redis数据库&#xff1a;MySQL权限控制&#xff1a;SpringSecurity工作流引擎&#xff1a;Activiti前端技术&#xff1a;vue-admin-template Node.js Npm Vue ElementUI Axios微信公众号&#xff1a;公众…

适合新手博主站长使用的免费响应式WordPress博客主题JianYue

这款JianYue主题之所以命名为 JianYue&#xff0c;意思就是简单而不简约的。是根据Blogs主题优化而成&#xff0c;剔除了一些不必要的功能及排版&#xff0c;仅保留一种博客布局&#xff0c;让新手站长能够快速手上WordPress。可以说这款主题比较适合新手博主站长使用&#xff…

B树的介绍

R-B Tree 简介特性B树特性m阶B树的性质&#xff08;这些性质是B树规定的&#xff09; B树的搜索B树的添加B树的删除——非叶子结点 简介 R-B Tree又称为Red-Black Tree&#xff0c;红黑树。是一种特殊的二叉查找树&#xff0c;红黑树的每个节点上都有存储为表示结点的颜色&…

源代码管理——码云Gitee

目录 Git安装 Gitee配置SSH 源代码管理常规操作 1.idea配置git 2.常规操作 Git安装 安装Git是进行源代码管理的基本步骤之一。以下是在本地安装Git的通用步骤&#xff0c;适用于Windows系统&#xff1a; 下载Git安装程序: 访问Git官网的下载页面&#xff1a;Git官网下载地…

2024 CKS 题库 | 12、Sysdig falco

不等更新题库 CKS 题库 12、Sysdig & falco Task&#xff1a; 使用运行时检测工具来检测 Pod tomcat123 单个容器中频发生成和执行的异常进程。 有两种工具可供使用&#xff1a; sysdigfalco 注&#xff1a; 这些工具只预装在 cluster 的工作节点 node02 上&#xff0c;…

信号处理 | 短时傅里叶变换实战

短时傅里叶变换(STFT)原理 短时傅里叶变换&#xff08;Short-Time Fourier Transform, STFT&#xff09;是一种分析时变信号频率特性的方法。它通过将长时间的信号分割成较短的时间片段&#xff0c;然后对每个时间片段进行傅里叶变换&#xff0c;从而克服了传统傅里叶变换无法…

【Java程序设计】【C00300】基于Springboot的足球社区管理系统(有论文)

基于Springboot的足球社区管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的足球社区管理系统&#xff0c;本系统有管理员以及教练角色权限&#xff1b; 管理员设置的功能有&#xff1a;添加并管理各种类型…

代码随想录day33-动态规划的应用1

LeetCode62.不同路径 题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 …

可视化 RAG 数据 — 用于检索增强生成的 EDA

原文地址&#xff1a;Visualize your RAG Data — EDA for Retrieval-Augmented Generation 2024 年 2 月 8 日 Github&#xff1a;https://github.com/Renumics/rag-demo/blob/main/notebooks/visualize_rag_tutorial.ipynb 为探索Spotlight中的数据&#xff0c;我们使用Pa…

linux 文本编辑命令【重点】

目录 vi&vim介绍 vim安装 vim使用 查找命令 find grep 文本编辑的命令&#xff0c;主要包含两个: vi 和 vim vi&vim介绍 作用: vi命令是Linux系统提供的一个文本编辑工具&#xff0c;可以对文件内容进行编辑&#xff0c;类似于Windows中的记事本 语法: vi file…

NXP实战笔记(十):S32K3xx基于RTD-SDK在S32DS上配置CAN通信

目录 1、概述 2、SDK配置 2.1、配置目标 2.2、CAN配置 3、代码实现 4、测试结果 1、概述 S32K3xx的FlexCan与之前的S32K1xx很相似,Can的中断掩码寄存器(IMASK3)与中断标志位寄存器(IFLAG3)依赖于邮箱数。 FlexCan配置实例如下 FlexCan的整体图示如下 Protocol Engine…

MiKTeX安装后,Latex编译后PDF无法预览,是灰色的

解决方式删掉编译器就可以&#xff0c; 即删掉MiKTeX MiKTeX安装后会将编译器默认修改为MiKTeX&#xff0c;这个时候会显示报错&#xff0c;简单粗暴的方式是删掉MiKTeX软件

程序员可以做什么副业呢?

如果你经常玩知乎、看公众号&#xff08;软件、工具、互联网这几类的&#xff09;你就会发现&#xff0c;好多资源连接都变成了夸克网盘、迅雷网盘的资源链接。 例如&#xff1a;天涯神贴&#xff0c;基本上全是夸克、UC、迅雷网盘的资源链接。 有资源的前提下&#xff0c;迅雷…

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒 1. 纳斯达克大屏的概述 纳斯达克大屏是全球金融市场中最出名的电子交易平台之一。作为一个重要的金融信息传递渠道&#xff0c;纳斯达克大屏吸引了来自全球的投资者的目光。在这个巨大的投放平台上&#xff0c;大舍传媒希望为客…

【机器学习基础】一元线性回归(适合初学者的保姆级文章)

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习 欢迎订阅&#xff01;后面的内容会越来越有意思~ &#x1f4a1;往期推荐&#xff1a; 【机器学习基础】机器学习入门&#xff08;1&#xff09; 【机器学习基…

python中的类与对象(1)

目录 一. 引子&#xff1a;模板 二. 面向过程与面向对象 &#xff08;1&#xff09;面向过程编程 &#xff08;2&#xff09;面向对象编程 三. 对象与类 &#xff08;1&#xff09;对象 &#xff08;2&#xff09;类 四. 面向对象程序设计的特点&#xff1a;封装&#…

互联网加竞赛 机器视觉opencv答题卡识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 答题卡识别系统 - opencv python 图像识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分…