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

news2024/11/27 0:22:52

一、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.Demo

E:\Zero.Apps\Python.Demo>virtualenv zero.demo.venv
created virtual environment CPython3.8.6.final.0-64 in 5946ms
  creator 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.0
  activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

E:\Zero.Apps\Python.Demo>cd zero.demo.venv

E:\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 django
  Downloading 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... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying 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 definition

INSTALLED_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/#databases

DATABASES = {
    '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 pysql
  Downloading pysql-0.16.tar.gz (127 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 127.4/127.4 kB 258.7 kB/s eta 0:00:00
  Preparing metadata (setup.py) ... error
  error: 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 31
          except 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 rows
 2) 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... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying serverapp.0001_initial... OK
  Applying serverapp.0002_order_person_create_at_person_name_person_phone_and_more... OK
  Applying 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_method
    return 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 filter
    return 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_exclude
    clone._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_inplace
    self._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_q
    clause, _ = 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_q
  File "D:\Zero.App\Python.Demo\zero.demo.venv\lib\site-packages\django\db\models\sql\query.py", line 1415, in build_filter
    lookups, 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_path
    raise 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_method
    return 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 get
    raise 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, include

urlpatterns = [
    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_views


urlpatterns = [
    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.coloradmin.cn/o/784657.html

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

相关文章

趋动科技携手星辰天合,推出针对人工智能领域的两款联合解决方案

近日&#xff0c;趋动科技与 XSKY星辰天合联合宣布&#xff0c;结合双方优势能力和产品&#xff0c;携手推出高性能数据湖一站式方案及全协议存算一体化方案&#xff0c;帮助客户简化 AI 工作的 IT 基础设施部署&#xff0c;实现 AI 相关工作更加灵活和便捷。 全协议存算一体化…

银河麒麟服务器安装wireshark

安装 yum install -y wireshark 界面展示 双击打开即可 上图为抓包工作界面

kubernetes持久化存储卷

kubernetes持久化存储卷 kubernetes持久化存储卷一、存储卷介绍二、存储卷的分类三、存储卷的选择四、本地存储卷之emptyDir五、本地存储卷之 hostPath六、网络存储卷之nfs七、PV(持久存储卷)与PVC(持久存储卷声明)7.1 认识pv与pvc7.2 pv与pvc之间的关系7.3 实现nfs类型pv与pvc…

通过cmake工程生成visual studio解决方案

1、前言 visual studio是一个很强大的开发工具&#xff0c;这个工具主要是通过解决方案对我们的源码进行编译等操作。但是我们很多时候拿到的可能并不是一个直接的解决方案&#xff0c;可能是是一个cmake工程&#xff0c;那么这个时候我们就需要通过cmake工程生成解决方案&…

力扣题库刷题笔记75--颜色分类

1、题目如下&#xff1a; 2、个人Pyhon代码实现如下&#xff1a; 第一种思路是取巧&#xff0c;通过计数0、1、2的个数&#xff0c;去替换nums 备注第10行代码在本地可以跑过&#xff0c;但是力扣跑不过&#xff0c;所以就用了第10-16行代码进行替换 第二种思路是通过冒泡排序去…

智慧导诊系统源码:基于springboot+redis+mybatis plus和mysql开发

智慧导诊系统源码 智慧导诊小程序源码&#xff0c;智慧导诊APP源码 人们经常去医院以不知道挂什么科而烦恼&#xff0c;有些病人不方便问又不好意思问。在互联网医院中挂号且又不知该挂什么科&#xff0c;找什么类型的医生&#xff0c;这些不足&#xff0c;给患者带来了极大的…

chrome macos编译

下载工具包 git clone https://chromium.googlesource.com/chromium/tools/depot_tools/gitpwd export PATH"$PATH:/Users/lichengjun/Downloads/chrome_build/depot_tools" mkdir chromium cd chromium 如果想快的话直接: fetch --nohooks --no-history chromium (…

深度学习(二)

目录 一、神经网络 整体架构: 架构细节: 神经元个数的影响: 神经网络过拟合解决: 卷积网络 整体架构: 卷积层 边缘填充 特征尺寸计算 池化层 特征图变化 递归神经网络 一、神经网络 整体架构: 图中分别为输入层、隐层1、隐层2、输出层 通过输入层输入某数值&#xf…

【Java基础教程】(四十四)IO篇 · 上:解析Java文件操作——File类、字节流与字符流,分析字节输出流、字节输入流、字符输出流和字符输入流的区别

Java基础教程之IO操作 上 &#x1f539;本节学习目标1️⃣ 文件操作类&#xff1a;File2️⃣ 字节流与字符流2.1 字节输出流&#xff1a;OutputStream2.2 字节输入流&#xff1a;InputStream2.3 字符输出流&#xff1a;Writer2.4 字符输入流&#xff1a;Reader2.5 字节流与字符…

删除git关联,提交到新的仓库

要删除git关联并创建一个新的git库&#xff0c;可以按照以下步骤操作&#xff1a; 进入你要处理的本地git仓库目录。 删除与远程仓库的关联&#xff1a; git remote remove origin初始化一个新的git仓库&#xff1a; git init添加所有文件到本地仓库&#xff1a; git add …

Redis高级篇(三)

Redis高级篇之最佳实践 Redis键值设计 批处理优化 Redis服务端优化 一、Redis键值设计 1.1、优雅的key结构 Redis的Key虽然可以自定义&#xff0c;但最好遵循下面的几个最佳实践约定&#xff1a; 遵循基本格式&#xff1a;[业务名称]:[数据名]:[id] 长度不超过44字节 不…

如何解决创建vue项目后没有webpack.config.js(vue.config.js)文件

◼️ webpack.config.js文件没有的原因 Vue 项目中 vue.config.js 文件就等同于 webpack 的 webpack.config.js。 vue-cli3 之后创建的时候并不会自动创建 vue.config.js&#xff0c;因为这个是个可选项&#xff0c;所以一般都是需要修改 webpack 的时候才会自己创建一个 vue…

【Mysql数据库面试01】内连接 左连接 右连接 全连接

【Mysql数据库】内连接 左连接 右连接 全连接 0.准备1.内连接1.1 SQL(不带where)1.2 SQL&#xff08;带where&#xff09;1.3总结 2.左连接2.1SQL&#xff08;不带where&#xff09;2.2SQL&#xff08;带where&#xff09;2.3总结 3.右连接3.1 SQL&#xff08;不带where&#x…

Sentinel nacos spring cloud 持久化配置---分布式/微服务流量控制

文章目录 sentinel控制台安装目标实现代码地址版本说明maven spring-cloud-starter-alibaba-sentinel依赖yml文件Nacos业务规则配置看源码配置规则SentinelProperties 总配置加载DataSourcePropertiesConfiguration 配置标准的nacos配置注册具体sentinel配置 外传 sentinel控制…

3dsmax制作一个机器人

文章目录 建模身子&#xff1a;眼睛&#xff1a;头饰&#xff1a;肩膀手臂腿调整细节 渲染导出objMarmoset Toolbag 3.08渲染给眼睛添加材质&#xff0c;设置为自发光添加背景灯光 建模 身子&#xff1a; 眼睛&#xff1a; 头饰&#xff1a; 肩膀 手臂 腿 调整细节 渲染 导出…

Hugging News #0724: Llama 2 登陆 Hugging Face、AI 开源游戏竞赛获奖选手公布!

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…

力扣热门100题之找到字符串中所有字母异位词【中等】

题目描述 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s “cbaebabacd”, p “ab…

Qt动画,Qt程序开场动画

设计思路&#xff1a;qt动画 让欢迎界面显示完全&#xff0c;然后缩放欢迎界面&#xff0c;缩放到一定层度就关闭界面&#xff0c;然后显示主界面并放大。 #pragma once #include <QtWidgets/QWidget> #include "ui_testwelcomeform.h" #include <QDialog&g…

npm 安装报错:源文本中存在无法识别的标记

npm install -g vue/cli 源文本中存在无法识别的标记。 所在位置 行:1 字符: 16 npm install -g <<<< vue/cli CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException FullyQualifiedErrorId : UnrecognizedToken 解决方…

TCL(Tool Command Language)学习(二)-----基本指令

一、控制流if If(判断条件){ 脚本语句 }elseif{判断条件}{ 脚本语句 }else { 脚本语句 } 脚本语句的{一定要写在上一行。 二、switch 语句 和 C 语言中中的 switch 语句一样 三、循环指令foreach 语法格式&#xff1a; foreach 变量 列表 循环主体 功能&#xff1a;…