Python学习笔记-Django框架基础,APP,数据模型,后台管理,路由

一、Django框架简介

Django框架是Python的常用web框架,遵循 MVC 设计模式的框架,采用了MTV的框架模式,即模型M,视图V和模版T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。

2019年12月2日,Django 3. 0发布  。

核心组件:

  1. ORM:用于创建模型的对象关系映射;
  2. 为最终用户设计较好的管理界面;
  3. URL 设计;
  4. 设计者友好的模板语言;
  5. 缓存系统。

二、安装Django框架

直接通过pip安装,安装虚拟机之后,可以安装到虚拟机中。

pip install django
E:\>cd E:\Zero.Apps\Python.DemoE:\Zero.Apps\Python.Demo>virtualenv zero.demo.venv
created virtual environment CPython3.8.6.final.0-64 in 5946mscreator CPython3Windows(dest=E:\Zero.Apps\Python.Demo\zero.demo.venv, clear=False, no_vcs_ignore=False, global=False)seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\lin_j\AppData\Local\pypa\virtualenv)added seed packages: pip==23.1.2, setuptools==68.0.0, wheel==0.40.0activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivatorE:\Zero.Apps\Python.Demo>cd zero.demo.venvE:\Zero.Apps\Python.Demo\zero.demo.venv>Scripts\activate(zero.demo.venv) E:\Zero.Apps\Python.Demo\zero.demo.venv>pip django
ERROR: unknown command "django"(zero.demo.venv) E:\Zero.Apps\Python.Demo\zero.demo.venv>pip install django
Collecting djangoDownloading Django-4.2.3-py3-none-any.whl (8.0 MB)---------------------------------------- 8.0/8.0 MB 20.4 MB/s eta 0:00:00
Collecting asgiref<4,>=3.6.0 (from django)Downloading asgiref-3.7.2-py3-none-any.whl (24 kB)
Collecting sqlparse>=0.3.1 (from django)Downloading sqlparse-0.4.4-py3-none-any.whl (41 kB)---------------------------------------- 41.2/41.2 kB 1.9 MB/s eta 0:00:00
Collecting backports.zoneinfo (from django)Downloading backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl (38 kB)
Collecting tzdata (from django)Downloading tzdata-2023.3-py2.py3-none-any.whl (341 kB)---------------------------------------- 341.8/341.8 kB 22.1 MB/s eta 0:00:00
Collecting typing-extensions>=4 (from asgiref<4,>=3.6.0->django)Downloading typing_extensions-4.7.1-py3-none-any.whl (33 kB)
Installing collected packages: tzdata, typing-extensions, sqlparse, backports.zoneinfo, asgiref, django
Successfully installed asgiref-3.7.2 backports.zoneinfo-0.2.1 django-4.2.3 sqlparse-0.4.4 typing-extensions-4.7.1 tzdata-2023.3[notice] A new release of pip is available: 23.1.2 -> 23.2
[notice] To update, run: python.exe -m pip install --upgrade pip

三、创建Django项目

3.1 创建一个Django项目

django-admin startproject projectname

在要创建项目的目录文件夹下用指令创建项目,根据输入的名字即可创建对应的django项目。

注意:项目名不能含有".",但是可以含有下划线。若使用虚拟环境,需要在虚拟环境下进行创建项目。

# 在虚拟环境下创建
(zero.demo.venv) PS D:\Zero.App\Python.Demo> django-admin startproject "ZeroDjangoDemo"
(zero.demo.venv) PS D:\Zero.App\Python.Demo> 

创建项目后可以查看到项目的基本文件夹信息:

3.2 运行程序

python  manage.py runserver
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...System check identified no issues (0 silenced).You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
July 20, 2023 - 14:12:13
Django version 4.2.3, using settings 'ZeroDjangoDemo.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.[20/Jul/2023 14:13:18] "GET / HTTP/1.1" 200 10664
Not Found: /favicon.ico
[20/Jul/2023 14:13:18] "GET /favicon.ico HTTP/1.1" 404 2118

需要切换到项目文件夹中,然后运行命令启动框架服务。

启动后,可以通过127.0.0.1:8000访问前台网页,提示创建项目成功:

3.3 数据迁移

python manage.py migrate
PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py migrate
Operations to perform:Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:Applying contenttypes.0001_initial... OKApplying auth.0001_initial... OKApplying admin.0001_initial... OKApplying admin.0002_logentry_remove_auto_add... OKApplying admin.0003_logentry_add_action_flag_choices... OKApplying contenttypes.0002_remove_content_type_name... OKApplying auth.0002_alter_permission_name_max_length... OKApplying auth.0003_alter_user_email_max_length... OKApplying auth.0004_alter_user_username_opts... OKApplying auth.0005_alter_user_last_login_null... OKApplying auth.0006_require_contenttypes_0002... OKApplying auth.0007_alter_validators_add_error_messages... OKApplying auth.0008_alter_user_username_max_length... OKApplying auth.0009_alter_user_last_name_max_length... OKApplying auth.0010_alter_group_name_max_length... OKApplying auth.0011_update_proxy_permissions... OKApplying auth.0012_alter_user_first_name_max_length... OKApplying sessions.0001_initial... OK
PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> 

同样需要在项目文件夹下创建。

3.4 创建超级管理员

python manage.py createsuperuser
PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py createsuperuser
Username (leave blank to use 'ljm'): zero
Email address:       
Password: 
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: n
Password: 
Password (again):
Superuser created successfully.

创建超级管理,注意输入密码的时候不能与邮箱一致,也不能位数太小,要求大于8位字符。

创建后,可以通过admin访问后台:

 输入超级管理员和密码后即可访问。

3.5 项目模板文件简介

文件说明
 settings.pyDjango的配置文件,配置具体的项目信息
urls.pyDjango的路由文件,配置访问的路径和对应的函数
wsgi.pyDjango的WSGI接口设置文件
manage.pyDjango的入口文件

 四、创建APP

4.1 创建APP

DJango项目中,推荐使用APP实现不同的模块功能,通过指令创建App,可创建多个app。

python manage.py startapp appname
(zero.demo.venv) PS E:\Zero.Apps\Python.Demo\ZeroDjangoDemo> python manage.py startapp serverapp 

注意:在虚拟环境下安装Django的需要在虚拟环境下才能正常运行。

文件说明
migrations迁移文件
__init__.py包标识文件
admin.pyDjango的后台文件
apps.py配置文件,配置单独添加的每个应用。
models.py数据库模型的文件
tests.py 用来编写测试脚本的文件
views.py视图控制器文件

通过创建APP可以独立开功能,让每个模块单独管理对应的数据。

4.2 将APP添加到项目的settings.py文件中

需要将APP添加到INSTALLED_APPS列表中,直接添加app名称。

# Application definitionINSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','serverapp',
]

五、Django中的数据模型

5.1 ORM简介

对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。通过ORM可以将对不同数据库的操作转换成操作统一的ORM,可以大大提高开发效率,虽然执行效率会有所降低。

5.2 在App的models中创建模型

 直接在models文件中创建类,类中的每个属性都与数据库中的字段一一对应。

class Person(models.Model):"""Person model."""name = models.CharField(max_length=10)"""名称"""phone = models.CharField(max_length=11)'''Phone number'''

如果存在公用字段或者相同的字段,可以先创建一个公共字段的model,然后其他模型继承该公共模型。

使用内部类Meta,给模型赋予元数据。模型的元数据即“所有不是字段的东西”,比如排序选项( ordering ),数据库表名( db_table ),或是阅读友好的单复数名( verbose_name 和 verbose_name_plural )。这些都不是必须的,并且在模型当中添加 Meta类 也完全是可选的。

from django.db import models# Create your models here.class CreateUpdate(models.Model):"""Create time and update time."""create_at = models.DateTimeField(auto_now_add=True)"""Create time"""update_at = models.DateTimeField(auto_now = True)"""Update time"""# 给模型赋予元数据class Meta: abstract = True  # 将model设置为抽象类,不会在数据库中创建表。class Person(CreateUpdate):"""Person model."""name = models.CharField(max_length=10)"""名称"""phone = models.CharField(max_length=11)'''Phone number'''class Order(CreateUpdate):"""Order model"""order_id  = models.CharField(max_length=20,db_index=True,primary_key=True)"""Order id"""order_desc = models.CharField(max_length=100)"""Order desc"""

创建模型时需要指定每个字段的类型,创建数据库时才能对应的创建不同类型的字段。

常见models的类型官网连接:模型字段参考 | Django 文档 | Django (djangoproject.com)https://docs.djangoproject.com/zh-hans/4.2/ref/models/fields/#django.db.models.DateField

5.3 数据库迁移

5.3.1 配置数据库

Django的默认数据库为SQLite数据库,但是可以根据自己的需求修改数据库,本文以mysql为例修改数据库配置。

其他数据库连接连接配置参考官网链接:

数据库 | Django 文档 | Django (djangoproject.com)https://docs.djangoproject.com/zh-hans/4.2/ref/databases/

(1)修改settings中的DATABASES设置

将默认的数据库设置:

# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databasesDATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}

修改成mysql对应的设置:

DATABASES = {'default': {"ENGINE": "django.db.backends.mysql",'NAME': 'djangodemo','USER': "root",'PASSWORD': "数据库密码",}
}

(2)在数据库中创建对应的表

我这边使用mysql自带的workbench客户端直接创建。

 (3)安装数据库驱动,mysql使用pymysql驱动:

使用pip安装pymysql模块。

pip install pymysql

注意,若使用虚拟环境需要在虚拟环境下安装。

(zero.demo.venv) PS D:\Zero.App\Python.Demo> pip install pysql
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/pysql/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/pysql/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/pysql/
Collecting pysqlDownloading pysql-0.16.tar.gz (127 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 127.4/127.4 kB 258.7 kB/s eta 0:00:00Preparing metadata (setup.py) ... errorerror: subprocess-exited-with-error× python setup.py egg_info did not run successfully.│ exit code: 1╰─> [7 lines of output]Traceback (most recent call last):File "<string>", line 2, in <module>File "<pip-setuptools-caller>", line 34, in <module>File "C:\Users\LJM\AppData\Local\Temp\pip-install-q4vyk2w_\pysql_8e28709aa008466d87288d7dded139fd\setup.py", line 31except Exception, e:^SyntaxError: invalid syntax[end of output]note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed× Encountered error while generating package metadata.
╰─> See above for output.note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
(zero.demo.venv) PS D:\Zero.App\Python.Demo> 

(4)修改APP的“__init__.py”文件,导入pymysql

import pymysql
pymysql.install_as_MySQLdb()        # 加此句可以使pymysql发挥最大数据库操作性能。

5.3.2 执行数据迁移命令

python manage.py makemigrations        # 生成迁移文件
python manage.py migrate               # 迁移数据库,创建对应的表
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py makemigrations
It is impossible to add the field 'create_at' with 'auto_now_add=True' to person without providing a default. This is because the database needs something to populate existing rows.1) Provide a one-off default now which will be set on all existing rows2) Quit and manually define a default value in models.py.
Select an option: 1
Please enter the default value as valid Python.
Accept the default 'timezone.now' by pressing 'Enter' or provide another value.
The datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value.
Type 'exit' to exit this prompt
[default: timezone.now] >>> timezone.now()
It is impossible to add a non-nullable field 'name' to person without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:1) Provide a one-off default now (will be set on all existing rows with a null value for this column)2) Quit and manually define a default value in models.py.
Select an option: 1
Please enter the default value as valid Python.
The datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value.
Type 'exit' to exit this prompt
>>> admin
Invalid input: name 'admin' is not defined
>>> "admin" 
It is impossible to add a non-nullable field 'phone' to person without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:1) Provide a one-off default now (will be set on all existing rows with a null value for this column)2) Quit and manually define a default value in models.py.
Please select a valid option: 1
Please enter the default value as valid Python.
The datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value.
Type 'exit' to exit this prompt
>>> "12345678910"
Migrations for 'serverapp':serverapp\migrations\0002_order_person_create_at_person_name_person_phone_and_more.py- Create model Order- Add field create_at to person- Add field name to person- Add field phone to person- Add field update_at to person
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py migrate       
Operations to perform:Apply all migrations: admin, auth, contenttypes, serverapp, sessions
Running migrations:Applying contenttypes.0001_initial... OKApplying auth.0001_initial... OKApplying admin.0001_initial... OKApplying admin.0002_logentry_remove_auto_add... OKApplying admin.0003_logentry_add_action_flag_choices... OKApplying contenttypes.0002_remove_content_type_name... OKApplying auth.0002_alter_permission_name_max_length... OKApplying auth.0003_alter_user_email_max_length... OKApplying auth.0004_alter_user_username_opts... OKApplying auth.0005_alter_user_last_login_null... OKApplying auth.0006_require_contenttypes_0002... OKApplying auth.0007_alter_validators_add_error_messages... OKApplying auth.0008_alter_user_username_max_length... OKApplying auth.0009_alter_user_last_name_max_length... OKApplying auth.0010_alter_group_name_max_length... OKApplying auth.0011_update_proxy_permissions... OKApplying auth.0012_alter_user_first_name_max_length... OKApplying serverapp.0001_initial... OKApplying serverapp.0002_order_person_create_at_person_name_person_phone_and_more... OKApplying sessions.0001_initial... OK
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> 

此处遇到一些问题,非空字段需要有默认值,需要选择对用的选项然后数据一些默认值进行创建。

5.3.3 创建的数据表展示

 创建表之后会自动创建一个主键id。

5.3.4 指定字段为主键

若要指定自己创建的字段为主键,只需要在models对应的字段中添加primary_key=True属性即可。

class Order(CreateUpdate):"""Order model"""order_id  = models.CharField(max_length=20,db_index=True,primary_key=True)"""Order id"""order_desc = models.CharField(max_length=100)"""Order desc"""

然后重新执行指令,一样要注意在对应的环境下执行。

(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py makemigrations
Migrations for 'serverapp':serverapp\migrations\0003_remove_order_id_alter_order_order_id.py- Remove field id from order- Alter field order_id on order
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py migrate       
Operations to perform:Apply all migrations: admin, auth, contenttypes, serverapp, sessions
Running migrations:Applying serverapp.0003_remove_order_id_alter_order_order_id... OK
(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> 

更新后,order_id就是我们设置的主键了(下图为sqlitestudio的界面视图)。

5.4 数据的基本操作API

演示直接在命令行中操作,需要在项目根目录下启用命令行,或者启动后切到项目目录下。

5.4.1 导入模块

(zero.demo.venv) PS D:\Zero.App\Python.Demo\ZeroDjangoDemo> python manage.py shell
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from serverapp.models import Person,Order

5.4.2 添加数据

# 方法1:直接使用create
>>> p = Person.objects.create(name = "xiaoming", phone = "123456")
# 方法2:先创建对象,然后调用save方法
>>> p = Person(name = "xiaoli", phone = "654321")
>>> p.save()        # 必须调用保存方法才能保存数据。

5.4.3 查询数据

(1)单表查询

# 查找所有数据
>>> Person.objects.all()
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 查找单个数据
>>> Person.objects.get(name = "xiaoli")
<Person: Person object (2)># 查询指定条件的数据
# 字段名 + __exact 表示字段值必须为该数据
>>> Person.objects.filter(name__exact = "xiaoli") 
<QuerySet [<Person: Person object (2)>]># 字段名 + __iexact 表示字段必须为设定值,且忽略大小写
>>> Person.objects.filter(name__iexact = "XIAOLI")
<QuerySet [<Person: Person object (2)>]># 字段名 + __gt 表示字段必须大于设定值
>>> Person.objects.filter(name__gt = 1)
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __lt 表示字段必须小于设定值
>>> Person.objects.filter(id__lt = 5)   
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __contains 表示字段包含设置值,可通过order_by排序
>>> Person.objects.filter(name__contains = "xiao").order_by("id")
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __icontains 表示字段包含设置值,并忽略大小写
>>> Person.objects.filter(name__icontains = "a")
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __startswith 表示以...开始
>>> Person.objects.filter(name__startswith = "xiao") 
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __istartswith 表示以...开始,并忽略大小写
>>> Person.objects.filter(name__istartswith = "XIAO") 
<QuerySet [<Person: Person object (1)>, <Person: Person object (2)>]># 字段名 + __endswith 表示以...结束
>>> Person.objects.filter(name__endswith = "li")   
<QuerySet [<Person: Person object (2)>]># 字段名 + __iendswith 表示以...结束,并忽略大小写
>>> Person.objects.filter(name__iendswith = "Li") 
<QuerySet [<Person: Person object (2)>]># 使用exclude方法可以排除满足条件的数据,与filter效果相反
>>> Person.objects.exclude(name = "xiaoli")          
<QuerySet [<Person: Person object (1)>]>

(2)跨关系查询(多表联查)

使用双下划线“__”分割模型的小写名称,直到查询到自己要的字段。

先创建关联字段:

class Order(CreateUpdate):"""Order model"""order_id  = models.CharField(max_length=20,db_index=True,primary_key=True)"""Order id"""order_desc = models.CharField(max_length=100)"""Order desc"""order_customer = models.ForeignKey(Person,related_name="Name",on_delete=models.CASCADE)"""link to person"""

 再搞几条数据:

以下是正向查找,使用Order表中的字段“order_customer”查找管理的persong的“name”字段 

>>> Order.objects.filter(order_customer__name = "xiaoli") 
<QuerySet [<Order: Order object (3)>, <Order: Order object (4)>]>

可以通过使用模型的小写名称激活反查,进行关系反差

>>> Person.objects.filter(order__order_id = 1)
<QuerySet [<Person: Person object (1)>]>

此处说一下:本人测试的时候刚开始出现了一个问题,就是进行发查的时候无法识别模块的小写名称,一直将模块名识别为字段名,报字段名称错误。一度重新迁移数据,重新进入django shell也是没有用,网上也没有搜到类似的问题。后面在多次尝试后,某一次推出shell,重新进入之后就可以了,而且也无法重新原来的问题。蛮记录下该问题。

错误信息如下:

>>> Person.objects.filter(order__order_id = 1) 
Traceback (most recent call last):File "<console>", line 1, in <module>File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_methodreturn getattr(self.get_queryset(), name)(*args, **kwargs)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\query.py", line 1436, in filterreturn self._filter_or_exclude(False, args, kwargs)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\query.py", line 1454, in _filter_or_excludeclone._filter_or_exclude_inplace(negate, args, kwargs)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\query.py", line 1461, in _filter_or_exclude_inplaceself._query.add_q(Q(*args, **kwargs))File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1534, in add_qclause, _ = self._add_q(q_object, self.used_aliases)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1565, in _add_qFile "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1415, in build_filterlookups, parts, reffed_expression = self.solve_lookup_type(arg, summarize)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1225, in solve_lookup_type_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1713, in names_to_pathraise FieldError(
django.core.exceptions.FieldError: Cannot resolve keyword 'order' into field. Choices are: Name, create_at, id, name, phone, update_at
>>> Order.objects.all()
<QuerySet [<Order: Order object (1)>, <Order: Order object (2)>, <Order: Order object (3)>, <Order: Order object (4)>]>

5.4.4 修改查询到的数据

先查询到具体数据,然后再进行修改:

>>> p = Person.objects.get(name = "xiaoli")    
>>> print(p) 
Person object (2)
>>> print(p.name + " " + p.phone) 
xiaoli 654321
>>> p.name = "xiaoxiaoderener" 
>>> p.save()        # 需要调用save方法才会保存修改
>>> p = Person.objects.get(id = p.id) 
>>> p.name
'xiaoxiaoderener'

或者可以使用get_or_create函数,如果不存在就直接创建。

# 注意,get_or_create返回的是元组,一个是数据对象,一个是布尔值
>>> p, is_created = Person.objects.get_or_create(name = "xiaoming")             
>>> p.name
'xiaoming'# 不存在时,直接创建一个数据
>>> p, is_created = Person.objects.get_or_create(name = "xiaolei")  
>>> p.name
'xiaolei'

此时发现数据库中添加了原来并不存在的xiaolei,但是非空字段phone是空的,算是一个bug。

 5.4.5 删除数据

返回的数据对象直接调用delete()方法,可以直接删除数据。

>>> p = Person.objects.get(id = 3) 
>>> p.name
'xiaolei'
>>> p.delete()
(1, {'serverapp.Person': 1})
>>> p = Person.objects.get(id = 3)
Traceback (most recent call last):File "<console>", line 1, in <module>File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_methodreturn getattr(self.get_queryset(), name)(*args, **kwargs)File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\query.py", line 637, in getraise self.model.DoesNotExist(
serverapp.models.Person.DoesNotExist: Person matching query does not exist.
>>>

大多数情况下,已经创建的数据不建议删除,而是添加一个状态字段,isenabled或者status之类的,用false标记不可用状态。

六 管理后台

6.1  Django后台管理配置流程

  1. 定义管理类:在app的admin.py中定义一个类继承admin.ModelAdmin。

  2. 配置信息:在类中定义信息

  3. 绑定模型到创建的类中:将模型注册到admin中。

from django.contrib import admin
from serverapp.models import Person# Register your models here.class PersonAdmin(admin.ModelAdmin):"""Admin class"""list_display = ("name","phone") # 配置显示信息admin.site.register(Person,PersonAdmin)     # 将Person模型绑定到PersonAdmin类中

6.2 进入管理后台

先启动服务器:

python manage.py runserver

然后在浏览器输入网址和管理后台地址:

http://127.0.0.1:8000/admin

在显示的用户登陆界面输入账号和密码登陆:

 即可进入后台管理页面,ServerApp就是我们自己的应用。

 

6.3 配置信息

6.3.1 配置后台显示语言

Django的默认后台显示语言是英文,可通过settings.py文件配置全局显示语言,修改后即可显示中文。

# 语言为中文
LANGUAGE_CODE = 'zh-Hans'
# 时区为亚洲上海
TIME_ZONE = 'Asia/Shanghai'

6.3.2 同时添加多个管理模块

(1)定义多个类,并且将类注册到django的admin中,可以通过后台管理多个模型。

class PersonAdmin(admin.ModelAdmin):"""Admin class"""list_display = ("name", "phone")  # 配置显示信息admin.site.register(Person, PersonAdmin)     # 将Person模型绑定到PersonAdmin类中class OrderAdmin(admin.ModelAdmin):"""Admin class"""list_display = ("order_id", "order_desc")  # 配置显示信息admin.site.register(Order, OrderAdmin)     # 将Order模型绑定到OrderAdmin类中

(2)当不同模型拥有相同的字段时,可以对相同的字段进行设置,然后以列表的形式将不同的模型绑定到同一个类中。不同的模型在后台以相同的配置信息进行管理。

class PersonAdmin(admin.ModelAdmin):"""Admin class"""#list_display = ("name", "phone")  # 配置显示信息list_display = ("create_at", "update_at")admin.site.register((Person,Order), PersonAdmin)     # 将Person,Order模型绑定到PersonAdmin类中

 6.3.3 常用配置信息介绍

(1)空值显示 empty_value_display

设置空值的显示内容,类中定义直接创建属性即可,输入的时候没有只能提示。

# 类中声明属性
class OederAdmin(admin.ModelAdmin):empty_value_display = "(None)"# 或者直接修改admin属性
admin.site.empty_value_display = "(None)"   # 覆盖控制显示内容

 (2)显示内容 list_display

以元组的形式设置显示的内容,元组的元素是模型中对应的字段。

class OrderAdmin(admin.ModelAdmin):"""Admin class"""list_display = ("order_id", "order_desc", "create_at")  # 配置显示信息

 (3) 数据过滤器 list_filter

以元组的形式添加过滤器,可以用于筛选数据。

class OrderAdmin(admin.ModelAdmin):"""Admin class"""list_display = ("order_id", "order_desc", "create_at")  # 配置显示信息list_filter = ("order_id", "create_at")

(4)搜索框 search_fields

以元组形式设置搜索字段,搜索使用的是模糊查找。

search_fields = ("order_id",)       # 搜索框

(5)设置只读字段 readonly_fields

设置字段为只读属性。

readonly_fields = ("order_id", "create_at")     # 设置只读字段

 七 路由(urls)

7.1 路由处理流程

  1. 查找全局的urls.py文件
  2. 按照先后顺序逐一匹配
  3. 匹配到之后停止
  4. 没有匹配到,进行异常处理

7.2 路由表达式

7.2.1 精确字符串格式

使用精确字符串格式查找,具体到对应的地址信息,url需要一致才能匹配。

forder/name

7.2.2 转换格式

使用<类型:参数名>格式时表示字符串进行转换格式,将传入的数据转换成需要的数据。

# 要求传入数据为int型,然后参数对应的是param
forder/<int:param>

7.2.3 正则表达式

使用re_path(表达字符串进行匹配),根据正则表达式进行识别。

# 直接匹配
re_path(forder/("正则表达式"))# 将匹配的数据传递给参数param
re_path(forder/(?P<param>"正则表达式"))

7.3 设置路由

7.3.1 找到全局路由配置文件 urls.py文件

 Django默认已经创建一个路由组“admin/”,对应的是一组路由,然后再令行进行细分。

7.3.2 创建一个自己的路由组

创建也给路由组“serverapp/”,作为serverapp所有路由的人口,使用include函数指定路由文件为server app下的urls.py文件。

from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('serverapp/', include("serverapp.urls")),      # 声明自己的路由组
]

7.3.3 在app下的urls中声明路由

在app的urls文件下声明路由,将路由指向对应的函数test

from django.urls import path,re_path
from serverapp import views as serverapp_viewsurlpatterns = [path('test/2023', serverapp_views.test),        # 精确匹配path('converter/<int:num>', serverapp_views.converter),         # 格式转换re_path(r'^re/(?P<num>[0-9]{1,4})/$', serverapp_views.rematch),         # 正则表达式,通过添加起止符限制匹配,避免中间多级路径后匹配到,造成错误匹配。
]

views下的函数定义:

from django.shortcuts import render
from django.http import HttpResponse# Create your views here.def test(request):"""method of test"""return HttpResponse("Hello World.")def converter(request, num):"""method of converter"""content = f"The number is : {num}"return HttpResponse(content)def rematch(request, num):"""method of re match"""content = f"The re match number is : {num}"return HttpResponse(content)

7.3.4 路由示例

精确查找结果: 

格式转换结果:

 正则匹配结果:

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

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

相关文章

新能源汽车的发展

目录 1.什么是新能源 2.什么是新能源汽车 3.新能源汽车的优点 4.新能源汽车的危害 5.新能源汽车未来的发展 1.什么是新能源 新能源是指与传统能源&#xff08;如化石燃料&#xff09;相比&#xff0c;更具可再生性、清洁性和低碳排放的能源形式。它主要通过利用自然资源和可…

Vue如何配置eslint

eslint官网: eslint.bootcss.com eslicate如何配置 1、选择新的配置&#xff1a; 2、选择三个必选项 3、再选择Css预处理器 4、之后选择处理器 5、选择是提交的时候就进行保存模式 6、放到独立的配置文件上去 7、最后一句是将自己的数据存为预设 8、配合console不要出现的规则…

【Java中的Thread线程的简单方法介绍和使用详细分析】

文章目录 前言一、run() 和 start() 方法二、sleep() 方法三、join() 方法总结 前言 提示&#xff1a;若对Thread没有基本的了解&#xff0c;可以先阅读以下文章&#xff0c;同时部分的方法已经在如下两篇文章中介绍过了&#xff0c;本文不再重复介绍&#xff01;&#xff01;…

在nginx上部署nuxt项目

先安装Node.js 我安的18.17.0。 安装完成后&#xff0c;可以使用cmd&#xff0c;winr然cmd进入&#xff0c;测试是否安装成功。安装在哪个盘都可以测试。 测试 输入node -v 和 npm -v&#xff0c;&#xff08;中间有空格&#xff09;出现下图版本提示就是完成了NodeJS的安装…

Windows OS CMD 常用工具 の 命令合集

# First Of All 每次想要修改环境变量都要按部就班点开系统属性、高级系统设置、环境变量。这种操作实在是太繁琐了&#xff0c;对于我一个懒人来讲实在是 忍无可忍 。如果可以使用 WINR 或 CMD 直接打开系统内的一些工具&#xff0c;是不是就可以节省很多时间&#xff1b;是不…

【node.js】01-fs读写文件内容

目录 一、fs.readFile() 读取文件内容 二、fs.writeFile() 向指定的文件中写入内容 案例&#xff1a;整理txt 需求&#xff1a; 代码&#xff1a; 一、fs.readFile() 读取文件内容 代码&#xff1a; //导入fs模块&#xff0c;从来操作文件 const fs require(fs)// 2.调…

【雕爷学编程】Arduino动手做(173)---SG90舵机双轴云台模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

windows配置anaconda环境变量

windows 配置 anaconda 环境变量&#xff0c;可以做到 cmd 中调用 conda 命令&#xff0c;不必每次都去找 Anaconda Prompt 文章目录 1. 找到Anaconda的安装位置2. 配置系统环境变量2.1 一步到位2.1 或者手动打开2.2 配置环境变量 3. 检查 1. 找到Anaconda的安装位置 默认安…

kafka面试题

kafka基本概念 Producer 生产者&#xff1a;负责将消息发送到 BrokerConsumer 消费者&#xff1a;从 Broker 接收消息Consumer Group 消费者组&#xff1a;由多个 Consumer 组成。消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费者消费&am…

Vue中TodoList案例_动画

MyItem.vue : 主要是引入了import animate.css样式库&#xff0c;animate.css样式库配置见上一篇文章animate.css样式库&#xff0c;然后再li标签外套了transition标签&#xff0c;引用了name里面的名称是animate.css拿过来的&#xff0c;绑定了enter-active-class和leave-act…

电脑硬盘指的是什么?电脑硬盘长什么样子呢

在很早之前就听说过电脑里面有硬盘&#xff0c;但是不知道电脑硬盘是什么样子&#xff0c;本章文章结合硬盘的接口类型&#xff0c;以及应用技术&#xff0c;说说与硬盘样式有关的知识 一。机械硬盘 如果从硬盘的应用技术来区分硬盘&#xff0c;一般分为两种&#xff0c;早些年…

2023年第三届能源、电力与电气工程国际会议 (CoEEPE 2023)

会议简介 Brief Introduction 2023年第三届能源、电力与电气工程国际会议(CoEEPE 2023) 会议时间&#xff1a;2023年11月22日-24日 召开地点&#xff1a;澳大利亚墨尔本 大会官网&#xff1a;www.coeepe.org 2023年第三届能源、电力与电气工程国际会议(CoEEPE 2023)由安徽大学、…

【大数据运维-ambari】自定义fair-scheduler.xml配置文件导致ambari-server启动失败

将自定义fair-scheduler.xml放到 /var/lib/ambari-server/resources/stacks/HDP/3.0/services/YARN/configuration目录下&#xff0c;重启ambari-server失败&#xff1a; 日志显示&#xff1a; 进ambari数据库查看发现数据应该是对的。 删掉之前自定义的文件fair-scheduler.x…

JavaScript function默认参数赋值前后顺序差异

1、(num1,num2num1) 当传值仅传一个参数时&#xff0c;先给到第一个参数即num1&#xff0c;num1再赋值给num2&#xff0c; function sum(num1, num2 num1) {console.log(num1 num2) } sum(10)//20 sum(10,3)//13 2、(t2t1,t1) 当传值仅有一个参数时&#xff0c;先给到第一个…

Qt 第一讲

登录框设置 #include "zuoye.h" #include "ui_zuoye.h"Zuoye::Zuoye(QWidget *parent): QWidget(parent), ui(new Ui::Zuoye) {ui->setupUi(this);//界面this->resize(540,420); //设置尺寸this->setFixedSize(540,420);//固定尺寸this->setS…

FPGA设计时序分析二、建立/恢复时间

目录 一、背景知识 1.1 理想时序模型 1.2 实际时序模型 1.2.1 时钟不确定性 1.2.2 触发器特性 二、时序分析 2.1 时序模型图 ​2.2 时序定性分析 一、背景知识 之前的章节提到&#xff0c;时钟对于FPGA的重要性不亚于心脏对于人的重要性&#xff0c;所有的逻辑运算都离开…

Unity光照相关知识和实践 (烘焙光照,环境光设置,全局光照)

简介 本文将会通过一个简单的场景搭建&#xff0c;介绍如何使用烘焙光照以及相关的注意事项。另外还介绍了Unity内全局光照&#xff08;GI&#xff09;的知识和GI实际在游戏内的表现效果。 Unity关于光照相关的参考文档地址&#xff1a;https://docs.unity.cn/cn/current/Man…

JAVA基础-集合(List与Map)

目录 引言 一&#xff0c;Collection集合 1.1,List接口 1.1.1&#xff0c;ArrayList 1.1.1.1&#xff0c;ArrayList的add&#xff08;&#xff09;添加方法 1.1.1.2&#xff0c;ArrayList的remove&#xff08;&#xff09;删除方法 1.1.1.3&#xff0c;ArrayList的contai…

web前端tips:js继承——借用构造函数继承

上篇文章给大家分享了 js继承中的原型链继承 web前端tips&#xff1a;js继承——原型链继承 在文章末尾&#xff0c;我提到了 原型链的继承&#xff0c;子类需要传递参数给父类的构造函数&#xff0c;就无法通过直接调用父类的构造函数来实现&#xff0c;需要通过中间的过程来…

Protobuf数据交互实战

"no one gonna make me down" 在之前呢&#xff0c;我们介绍了什么protobuf以及它的语法、数据类型。 一句老话说得好&#xff0c;"多说不练&#xff0c;假把式&#xff01;"。因此&#xff0c;本篇会选择以protobuf的语法&#xff0c;完成一个简易的通讯…