首页 > 数据库 >Django+MySQL接口开发完全指南

Django+MySQL接口开发完全指南

时间:2024-10-23 09:50:56浏览次数:8  
标签:models self 接口 django framework api MySQL import Django

前言

本文将详细介绍如何使用Django结合MySQL数据库开发RESTful API接口。我们将从环境搭建开始,一步步实现一个完整的接口项目。

环境准备

首先需要安装以下组件:

  • Python 3.8+
  • Django 4.2
  • MySQL 8.0
  • mysqlclient
  • djangorestframework

安装命令

# 创建虚拟环境
python -m venv venv
source venv/bin/activate  # Windows使用 venv\Scripts\activate

# 安装依赖
pip install django==4.2
pip install mysqlclient
pip install djangorestframework

项目创建与配置

1. 创建项目

django-admin startproject myproject
cd myproject
python manage.py startapp api

2. 配置settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',  # 添加rest_framework
    'api',  # 添加api应用
]

# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_demo',
        'USER': 'root',
        'PASSWORD': 'your_password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

# REST框架配置
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}

数据库模型设计

1. 创建模型(api/models.py)

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100, verbose_name='书名')
    author = models.CharField(max_length=50, verbose_name='作者')
    price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='价格')
    publish_date = models.DateField(verbose_name='出版日期')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'books'
        verbose_name = '图书'
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

    def __str__(self):
        return self.title

2. 生成并应用数据库迁移

python manage.py makemigrations
python manage.py migrate

序列化器开发

1. 创建序列化器(api/serializers.py)

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'price', 'publish_date', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']

视图开发

1. 创建视图(api/views.py)

from rest_framework import viewsets, filters
from rest_framework.response import Response
from rest_framework.decorators import action
from django_filters.rest_framework import DjangoFilterBackend
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['author']
    search_fields = ['title', 'author']
    ordering_fields = ['price', 'publish_date']

    @action(detail=False, methods=['get'])
    def get_book_stats(self, request):
        """获取图书统计信息"""
        total_books = Book.objects.count()
        total_authors = Book.objects.values('author').distinct().count()
        avg_price = Book.objects.aggregate(avg_price=models.Avg('price'))

        return Response({
            'total_books': total_books,
            'total_authors': total_authors,
            'average_price': avg_price['avg_price']
        })

URL配置

1. 配置项目URLs(myproject/urls.py)

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from api.views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
]

中间件开发

1. 创建自定义中间件(api/middleware.py)

import time
from django.utils.deprecation import MiddlewareMixin
import logging

logger = logging.getLogger(__name__)

class RequestLogMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.start_time = time.time()

    def process_response(self, request, response):
        if hasattr(request, 'start_time'):
            duration = time.time() - request.start_time
            logger.info(f'{request.method} {request.path} - {response.status_code} - {duration:.2f}s')
        return response

2. 在settings.py中注册中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'api.middleware.RequestLogMiddleware',  # 添加自定义中间件
]

异常处理

1. 创建自定义异常处理(api/exceptions.py)

from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status

def custom_exception_handler(exc, context):
    response = exception_handler(exc, context)

    if response is None:
        return Response({
            'error': str(exc),
            'message': '服务器内部错误'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response

2. 在settings.py中配置异常处理器

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'api.exceptions.custom_exception_handler'
}

API接口测试

1. 创建测试用例(api/tests.py)

from rest_framework.test import APITestCase
from rest_framework import status
from .models import Book
from datetime import date

class BookTests(APITestCase):
    def setUp(self):
        self.book_data = {
            'title': 'Django实战',
            'author': '张三',
            'price': '59.99',
            'publish_date': '2024-01-01'
        }
        self.book = Book.objects.create(**self.book_data)

    def test_create_book(self):
        """测试创建图书"""
        response = self.client.post('/api/books/', self.book_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Book.objects.count(), 2)

    def test_get_book_list(self):
        """测试获取图书列表"""
        response = self.client.get('/api/books/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)

API接口文档

使用drf-yasg生成Swagger文档:

1. 安装drf-yasg

pip install drf-yasg

2. 配置settings.py

INSTALLED_APPS = [
    ...
    'drf_yasg',
]

3. 配置URLs(myproject/urls.py)

from django.urls import path, include, re_path
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="图书管理API",
      default_version='v1',
      description="图书管理系统API文档",
      terms_of_service="https://www.yourapp.com/terms/",
      contact=openapi.Contact(email="[email protected]"),
      license=openapi.License(name="BSD License"),
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    ...
    re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

接口使用示例

1. 创建图书

curl -X POST http://localhost:8000/api/books/ \
     -H "Content-Type: application/json" \
     -d '{"title":"Django实战","author":"张三","price":"59.99","publish_date":"2024-01-01"}'

2. 获取图书列表

curl http://localhost:8000/api/books/

3. 更新图书

curl -X PUT http://localhost:8000/api/books/1/ \
     -H "Content-Type: application/json" \
     -d '{"title":"Django实战(第二版)","author":"张三","price":"69.99","publish_date":"2024-01-01"}'

4. 删除图书

curl -X DELETE http://localhost:8000/api/books/1/

性能优化建议

  1. 使用数据库索引
    class Book(models.Model):
        ...
        class Meta:
            indexes = [
                models.Index(fields=['title']),
                models.Index(fields=['author']),
            ]
  2. 使用缓存
    from django.core.cache import cache
    
    class BookViewSet(viewsets.ModelViewSet):
        def list(self, request):
            cache_key = 'book_list'
            cached_data = cache.get(cache_key)
            
            if cached_data is None:
                queryset = self.filter_queryset(self.get_queryset())
                serializer = self.get_serializer(queryset, many=True)
                cached_data = serializer.data
                cache.set(cache_key, cached_data, timeout=300)  # 缓存5分钟
                
            return Response(cached_data)

总结

本文详细介绍了使用Django开发RESTful API的完整流程,包括:

  1. 环境搭建和项目配置
  2. 数据库模型设计
  3. 序列化器开发
  4. 视图和URL配置
  5. 中间件和异常处理
  6. 测试用例编写
  7. API文档生成
  8. 性能优化建议

通过按照本教程的步骤,你可以快速搭建一个功能完善的Django API项目。建议在实际开发中根据具体需求进行适当调整和扩展。

 

标签:models,self,接口,django,framework,api,MySQL,import,Django
From: https://blog.csdn.net/Play_Sai/article/details/143175893

相关文章

  • 前端vue-接口的调用和特殊组件的封装
                 ......
  • MySQL【知识改变命运】11
    联合查询6.⼦查询6.1语法6.2单⾏⼦查询6.3多⾏⼦查询6.4多列⼦查询6.5在from⼦句中使⽤⼦查询7.合并查询7.1创建新表并初始化数据7.2Union7.3Unionall8.插⼊查询结果8.1语法8.2⽰例6.⼦查询⼦查询是把⼀个SELECT语句的结果当做别⼀个SELECT语句的......
  • MySQL DQL 10.22
    --一基础查询--1查询多个字段--SELECT字段列表FROM表名 ;--SELECT*FROM表名;--查询所有数据--2去除重复记录--SELECTDISTINCT字段列表FROM表名;--3起别名--AS--AS也可以省略--selectname,sexas性别fromstu;--selectDISTINCTnamefromstu......
  • flask 接口还在执行中,前端接收到接口请求超时,解决方案
    在Flask中,当某个接口执行时间较长而导致前端请求超时时,需要考虑以下解决方案:1.优化接口的响应时间如果可能,先优化接口中的代码逻辑,减少处理时间。对于查询操作,可以考虑数据库索引优化、缓存机制等手段。2.增加请求超时时间如果接口确实需要较长时间完成,前端可以......
  • Mysql基础命令总结
    1.DDL1.1操作数据库和表DataDefinitionLanguage数据定义语言Create,Retrieve(查询),update,Delete1.1.1操作数据库显示所有数据库:showdatabases;显示创建得数据库:showcreatedatabase数据库名称;创建一个数据库:createdatabase数据库名称;创建数据库前先判断是......
  • IO接口
    IO接口,又称IO控制器、设备控制器,负责协调主机与外部设备之间的数据传输IO接口的作用进行地址译码和设备选择。CPU送来选择外设的地址码后,接口必须对地址进行译码以产生设备选择信息,使主机能和指定外设交换信息。实现主机和外设的通信联络控制。解决主机与外设时序配合问题,协......
  • MySQL学习笔记
    目录基础篇:通用语法:基础操作:DDL-数据库操作:基本指令:数据类型:数值类型:字符串类型:日期时间类型:表结构修改:DML-增、删、改操作:插入操作:修改、删除操作:DQL-查询操作:DQL-编写顺序:基础查询:条件查询:分组查询:聚合函数:语法:排序查询:分页查询:DQL-执行顺序:DCL-用户管理:DCL-权限控制:函数:字符串......
  • 如何实现聚水潭·奇门销售数据与MySQL的高效对接
    聚水潭·奇门数据集成到MySQL的技术案例分享在现代企业的数据管理中,如何高效、准确地实现不同系统之间的数据对接和集成是一个重要的课题。本文将聚焦于一个具体的系统对接案例:将聚水潭·奇门平台上的销售出库单数据集成到MySQL数据库中的BI智选-销售出库表。为了确保数据集成......
  • Java调用第三方接口、http请求详解,一文学会
    系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:第一章Python机器学习入门之pandas的使用提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录系列文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据......
  • 【java】抽象类和接口(了解,进阶,到全部掌握)
    各位看官早安午安晚安呀如果您觉得这篇文章对您有帮助的话欢迎您一键三连,小编尽全力做到更好欢迎您分享给更多人哦大家好我们今天来学习Java面向对象的的抽象类和接口,我们大家庭已经来啦~一:抽象类1.1:抽象类概念在面向对象的概念中,所有的对象都是通过类来描绘的,但是......