1. Django 项目文件结构
1. 项目级文件
manage.py
-
作用:Django 项目的命令行工具,用于启动本地服务器、运行测试、创建数据库、执行迁移等操作。这是与项目交互的主要方式之一。
-
来源:Django 自动生成
settings.py
-
作用:Django 项目的全局配置文件,包含了数据库配置、静态文件路径、模板路径、中间件、时区设置、SESSION 设置、DEBUG 配置等。几乎所有的项目级配置都在这里进行。
-
示例配置:如 INSTALLED_APPS 用于注册应用,DATABASES 用于配置数据库连接,STATIC_URL 和 STATIC_ROOT 用于静态资源的配置。
-
来源:Django 自动生成,用户需根据项目需求进行修改。
urls.py
-
作用:Django 项目的路由文件,定义了 URL 与视图函数之间的映射关系。这是 Django 处理用户请求的第一步,根据请求的 URL 转发到相应的视图函数。
-
示例配置:通过 urlpatterns 列表定义路由,使用 path() 或 re_path() 等函数进行 URL 的匹配和视图函数的关联。
-
来源:Django 自动生成,用户需根据项目需求进行修改。
wsgi.py
-
作用:Web应用(Django)与Web服务器(如uWSGI)之间的桥梁,用于处理Web服务器发来的请求并返回响应。这是 Django 部署到生产环境时的重要文件。
-
来源:Django 自动生成
asgi.py(可选)
-
作用:ASGI(Asynchronous Server Gateway Interface)的实现,是 WSGI 的升级版本,支持异步视图,从而可以增大 Django 的并发量。适用于需要高并发的场景。
-
来源:在某些 Django 版本或配置中自动生成,不是所有项目都必需。
2. 应用级文件
在 Django 中,应用(App)是项目的基本构建块,每个应用都包含自己的视图、模板、模型等文件。
models.py
-
作用:定义数据模型,即数据库中的表结构(定义表结构,用于视图函数进行操作)。通过定义模型类及其属性,Django 能够自动生成数据库表,并进行数据的增删改查操作。
-
示例:定义一个 User 模型类,包含 username 和 email 等属性,Django 会自动生成相应的数据库表。
views.py
-
作用:定义视图函数,即处理用户请求并返回响应的函数(功能函数)。视图函数接收请求(request),执行相应的业务逻辑,并返回响应(response)。
-
示例:定义一个视图函数 home,用于处理首页的请求,并返回首页的 HTML 内容。
urls.py(应用级)
-
作用:定义应用内的路由,即应用内部 URL 与视图函数之间的映射关系。这是应用内部处理请求的第一步,也就是定义指向视图函数的接口
-
示例:通过 urlpatterns 列表定义应用内的路由,使用 path() 或 re_path() 等函数进行 URL 的匹配和视图函数的关联。
admin.py
-
作用:定义 Django 后台管理界面的配置,如注册模型到后台,设置后台的显示字段等。通过 Django 自带的后台管理界面,可以方便地对数据库进行增删改查操作。
-
示例:使用 admin.site.register(ModelClass) 将模型类注册到后台管理界面。
forms.py(可选)
-
作用:定义表单类,用于处理用户提交的表单数据。表单类可以定义表单的字段、验证规则等,使得表单处理更加灵活和方便。
-
示例:定义一个注册表单类,包含用户名、密码等字段,并设置相应的验证规则。
3. 其他目录和文件
templates 目录
-
作用:存储 HTML 模板文件的目录。Django 在渲染页面时,会查找这个目录下的模板文件。
-
配置:需要在 settings.py 的 TEMPLATES 配置中指定模板文件的路径。
static 目录
-
作用:存储静态文件的目录,如 CSS、JavaScript、图片等。这些文件通常被浏览器直接访问,而不是通过 Django 的视图函数处理。
-
配置:需要在 settings.py 中配置静态文件的 URL 和文件路径。
media 目录(可选)
-
作用:存储用户上传的媒体文件,如图片、视频等。
myproject/ │ ├── myapp/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations/ │ │ └── ... │ ├── models.py # LimitQuota模型定义 │ ├── serializers.py # LimitQuotaSerializer序列化器定义 │ ├── tests.py │ ├── urls.py │ └── views.py # LimitQuotaViewSet或单独的视图函数定义 │ ├── myproject/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py
2. 定义URL模式(接口入口)
如何定义url模式?并将其映射到视图函数?
-
首先定义视图函数view.py,也可以是views文件夹下新建功能函数
# views.py
from django.http import HttpResponse
#这个函数将处理对应的HTTP请求,并返回一个HTTP响应。
def my_view(request):
return HttpResponse("Hello, world!")
-
在应用级定义url模式(url.py),使用
path()
或url()
函数来定义URL模式,这个函数将URL模式(一个字符串)映射到之前定义的视图函数。# urls.py from django.urls import path from . import views # 'hello/'是URL模式,views.my_view是视图函数,'my-view'是这个URL模式的名称 # 这个名称是可选的,但它允许你在Django的模板和其他地方通过这个名字来引用这个URL)。 urlpatterns = [ path('hello/', views.my_view, name='my-view'), ]
-
若Django项目包含多个应用,并且每个应用都有自己的
urls.py
文件,那么你还需要在项目的根urls.py
文件中包含这些应用的URL配置。用include()
函数来实现的
# 项目根目录下的urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('myapp/', include('myapp.urls')), # 假设应用名为myapp
]
此时 ,include('myapp.urls')
告诉Django去查找myapp
应用目录下的urls.py
文件,并将该文件中定义的URL模式添加到当前项目的URL配置中。这样,当你访问/myapp/hello/
时,Django就会找到并调用myapp
应用中的my_view
视图函数。
3. 视图函数(接口=功能函数)
视图函数是处理Web请求并返回Web响应的核心部分。编写视图函数时,需要遵循Django的MVC(模型-视图-控制器)架构中的“视图”部分,尽管Django更倾向于称之为MTV(模型-模板-视图),但核心思想是一致的。
class Quota_limit(viewsets.ViewSet):
def list(self, request, *args, **kwargs):
try:
LOG.info("开始处理请求")
name = request.GET.get('name')
quota_limit = request.GET.get('quota_limit')
# 初始化查询集
queryset = LimitQuota.objects.filter()
LOG.info(queryset.query)
# 应用过滤条件
if name:
queryset = queryset.filter(name=name)
if quota_limit:
queryset = queryset.filter(quota_limt=quota_limit)
# 提取需要的数据
data = queryset.values()
if data:
LOG.info(f"提取的数据: {data}")
return util.wrapper_200(data=data)
except Exception as e:
LOG.info("查询过程中出现异常")
LOG.exception(e)
return util.wrapper_500("查询失败")
def check_data(data):
# 验证数据
if 'name' not in data or not isinstance(data['name'], str) or not data['name'].strip():
raise ValidationError('name 必须是非空字符串')
if 'quota_limit' not in data or not isinstance(data['quota_limit'], dict):
raise ValidationError('quota_limit 必须是非空字典')
quota_limit_data = data['quota_limit']
if 'NF' not in quota_limit_data or 'IPS' not in quota_limit_data or 'waf' not in quota_limit_data:
raise ValidationError("quota_limit 字典中缺少必需的键: NF, IPS, waf")
def create(self, request, *args, **kwargs):
try:
# 验证数据合法性
Quota_limit.check_data(request.data)
# 提取必要的数据
name = request.data.get('name')
quota_limit = request.data.get('quota_limit')
desc = request.data.get('desc')
# 创建新的 LimitQuota 实例
new_limit_quota = LimitQuota.objects.create(
name=name,
quota_limit=quota_limit,
desc=desc,
gmt_create=timezone.now(),
gmt_change=timezone.now()
)
# 返回成功响应
return Response({'message': '创建成功', 'id': new_limit_quota.id}, status=status.HTTP_201_CREATED)
except ValidationError as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
3. ORM(对象关系映射)
ORM(Object Relational Mapping,对象关系映射)是Django框架中的一个重要部分,它实现了面向对象编程语言中不同类型系统的数据之间的转换。ORM在业务逻辑层和数据库层之间充当了桥梁的作用,通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。这样做极大地减轻了开发人员的工作量,因为开发人员可以专注于编写Python代码,而不需要直接编写SQL语句。
-
ORM的模型定义
模型(model.py)是用Python类定义的,这些类映射到数据库中的表。每个模型的属性(类的变量)对应表中的列。Django提供了多种字段类型来定义模型的属性,这些字段类型被定义在django.db.models.fields
目录下,并为了方便使用而被导入到django.db.models
中。
定义模型时,需要先导入from django.db import models
,然后通过models.Field
创建字段类型的对象,赋值给类的属性。
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
class Author(models.Model):
name = models.CharField(max_length=100)
Book
和Author
是两个模型,分别对应数据库中的book
和author
表。Book
模型有一个title
字段和一个指向Author
模型的外键字段author
。
-
数据库迁移
模型定义完成后,需要通过数据库迁移(migrations)来将模型同步到数据库中。数据库迁移是Django ORM的一个核心功能,它允许你通过Python代码来管理数据库的结构变更。
数据库迁移的基本步骤如下:
-
编写Model类:在应用的
models.py
文件中定义模型。 -
生成迁移文件:运行
python manage.py makemigrations
命令。这个命令会检查models.py
中的变更,并生成一个或多个迁移文件,这些文件记录了模型的变更历史。 -
应用迁移:运行
python manage.py migrate
命令。这个命令会将迁移文件应用到数据库中,创建或修改表结构以匹配当前的模型定义。
-
数据库查询
Django ORM提供了丰富的API来进行数据库查询。可以使用这些API来执行复杂的查询操作,而不需要编写SQL语句。
以下是一些常用的查询操作示例:
-
查询所有数据:
Model.objects.all()
-
根据条件查询数据:
Model.objects.filter(field_name='value')
-
查询单条数据:
Model.objects.get(field_name='value')
-
排序和分页:
Model.objects.order_by('field_name')[start:end]
-
聚合查询:使用
Sum
、Count
等聚合函数 -
分组查询:使用
values
和annotate
进行分组和聚合
其中Model
是定义的类,这些类映射到数据库中的表,Field
是定义的数据库表中的列
Django ORM还支持更复杂的查询操作,如F查询、Q查询、原生SQL查询等。
4. Serializers(序列化器)
序列化器(Serializers)主要用于将Django模型实例转换成JSON、XML或其他内容类型,同时也支持将这些内容类型的数据反序列化为Django模型实例。虽然Django本身不直接提供序列化器,但Django REST framework(DRF)是一个广泛使用的第三方库,它提供了强大的序列化器支持。
-
序列化:将复杂的类型(如Django模型实例)转换成Python数据类型,然后可以轻松地将这些数据类型渲染成JSON、XML或其他内容类型。
-
反序列化:将请求数据(如JSON)解析成Python数据类型,然后可以将这些数据用于验证并转换为Django模型实例。
-
序列化器基本使用
-
定义序列化器
定义一个序列化器类,该类继承自rest_framework.serializers.Serializer
(对于简单用途)或rest_framework.serializers.ModelSerializer
(对于与Django模型交互的用途)。在类中,需要定义与数据模型字段相对应的字段。
from rest_framework import serializers
from .models import MyModel
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__' # 或者指定具体的字段,如 fields = ['field1', 'field2']
-
序列化Django模型实例
from .models import MyModel
from .serializers import MyModelSerializer
# 获取模型实例
my_model_instance = MyModel.objects.get(id=1)
# 序列化实例
serializer = MyModelSerializer(my_model_instance)
serializer.data # 这是序列化后的数据,通常是字典类型
-
反序列化通常用于处理客户端发送的数据(如POST请求)
from rest_framework.exceptions import ValidationError
# 假设这是从客户端接收到的JSON数据
data = {'field1': 'value1', 'field2': 'value2'}
# 反序列化数据
serializer = MyModelSerializer(data=data)
if serializer.is_valid():
serializer.save() # 如果数据有效,则保存新实例或更新现有实例
else:
raise ValidationError(serializer.errors) # 如果有错误,抛出异常
-
使用序列化器对数据进行验证和序列化
序列化器定义
在myapp/serializers.py
文件中,定义LimitQuotaSerializer
类
#接第三节例子,运用序列化器进行改进
from rest_framework import serializers
class LimitQuotaSerializer(serializers.Serializer):
name = serializers.CharField(required=True, allow_blank=False, help_text="必须是非空字符串")
quota_limit = serializers.IntegerField(required=True, help_text="必须是整数")
desc = serializers.CharField(required=False, allow_blank=True, help_text="描述信息(可选)")
def validate_name(self, value):
# 这里可以添加更复杂的验证逻辑
if not value.strip():
raise serializers.ValidationError("name 不能是空白字符串")
return value
def validate_quota_limit(self, value):
# 这里也可以添加额外的验证逻辑,但在这个例子中我们只需要它是一个整数
return value
def validate(self, attrs):
# 这里可以添加跨字段的验证逻辑
return attrs
视图函数定义
myapp/views.py
或myapp/views/quota_limit.py
文件中,定义处理请求的视图
# myapp/views.py
from rest_framework import viewsets, status
from rest_framework.response import Response
from django.utils import timezone
from .models import LimitQuota # 假设LimitQuota模型定义在这里
from .serializers import LimitQuotaSerializer # 导入序列化器
class LimitQuotaViewSet(viewsets.ViewSet):
def create(self, request, *args, **kwargs):
serializer = LimitQuotaSerializer(data=request.data)
if serializer.is_valid():
name = serializer.validated_data['name']
quota_limit = serializer.validated_data['quota_limit']
desc = serializer.validated_data.get('desc', '')
new_limit_quota = LimitQuota.objects.create(
name=name,
quota_limit=quota_limit,
desc=desc,
gmt_create=timezone.now(),
gmt_change=timezone.now() # 注意:请根据您的模型字段名进行调整
)
return Response({'message': '创建成功', 'id': new_limit_quota.id}, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# ... 其他视图方法 ...