博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于DRF的图书增删改查
阅读量:5151 次
发布时间:2019-06-13

本文共 10790 字,大约阅读时间需要 35 分钟。

功能演示

信息展示

添加功能

编辑功能

删除功能

DRF构建后台数据

本例的Model如下

from django.db import modelsclass Publish(models.Model):    name = models.CharField(max_length=32)class Author(models.Model):    name = models.CharField(max_length=32,verbose_name='姓名')class Book(models.Model):    title = models.CharField(verbose_name='书名',max_length=56)    price = models.DecimalField(verbose_name='价格',max_digits=8,decimal_places=2)    pub_date = models.DateField(verbose_name='出版日期')    publish = models.ForeignKey(to=Publish,on_delete=models.CASCADE)    authors = models.ManyToManyField(to=Author)

注册DRF

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'book.apps.BookConfig',    'rest_framework',]

路由分发如下

# 查看与新增—— GET与POSTurl(r'^books/$',views.BookListView.as_view(),name='book_get_post'),# 修改与删除—— PUT与DELETEurl(r'^book/(?P
\d+)/$',views.BookView.as_view(),name='book_put_delete'),

视图函数如下

from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom book import modelsfrom book.my_serializer import BookSerializerclass BookListView(APIView):    def get(self, request, *args, **kwargs):        """ 获取书籍信息 """               # 用自定义的序列化器去实现~~~        all_books = models.Book.objects.all()        # 第一个参数是instance~是一个对象        # 但是all()方法查出来的是一个“对象列表”——所以需要加many=True        ser_obj = BookSerializer(all_books, many=True)        # 返回自定义序列化器的data        return Response(ser_obj.data)    def post(self, request, *args, **kwargs):        """新增数据 返回新建的书籍的数据 json格式 """        # 用序列化器进行校验!!!        # 注意:这里用的是request.data去取新增的值!!!        print('>>>>>>',request.data)        ser_book = BookSerializer(data=request.data)        if ser_book.is_valid():            ser_book.save()            # 校验成功并且成功保存的话~返回新增的数据!            return render(request,'book_list.html')        else:            print(ser_book.errors)            return Response(ser_book.errors)class BookView(APIView):    def get(self,request,pk,*args,**kwargs):        # 找Model对象        book_obj = models.Book.objects.filter(pk=pk).first()        # 序列化器对象——此时instance只有一个book_obj,不用加many=True了!        ser_obj = BookSerializer(instance=book_obj)        # 用Response方法返回序列化器对象的data        return Response(ser_obj.data)    def put(self,request,pk,*args,**kwargs):        book_obj = models.Book.objects.filter(pk=pk).first()        # partial=True —— 表示支持“部分提交/局部更新”        ser_obj = BookSerializer(instance=book_obj,data=request.data,partial=True)        if ser_obj.is_valid():            ser_obj.save()            return Response(ser_obj.data)        else:            return Response(ser_obj.errors)    # 删除方法不需要用序列化器了    def delete(self,request,pk,*args,**kwargs):        obj = models.Book.objects.filter(pk=pk).first()        if obj:            obj.delete()            return Response({
'msg':'删除成功!'}) else: return Response({
"error":'数据不存在!'})

自定义的序列化器代码如下

# -*- coding:utf-8 -*-from rest_framework import serializersfrom book import modelsclass PublishSerializer(serializers.Serializer):    id = serializers.IntegerField(read_only=True)    name = serializers.CharField()class AuthorSerializer(serializers.Serializer):    id = serializers.IntegerField()    name = serializers.CharField()class BookSerializer(serializers.Serializer):    # 与Book中的属性对应上    # id 也需要~后面编辑与删除用得到~~设置read_only,添加的时候不必填    id = serializers.IntegerField(read_only=True)    title = serializers.CharField()    price = serializers.DecimalField(max_digits=8,decimal_places=2)    pub_date = serializers.DateField()    # 外键的~这个字段其实存的是id~~注意这里是publish_id——数据库中存储的字段~~但是这种方式只能拿到id值    # publish_id = serializers.IntegerField()    # 多对一 外键关联~    # 如果我们想拿publish的name的话,就需要交给上一个序列化器PublishSerializer去处理    # 提交的时候~~不用填这个,所以设置required=False    # 只有get请求要他而post请求不用它~所以设置 read_only=True    publish = PublishSerializer(required=False,read_only=True)    # 多对多~    # 只有get请求要他而post请求不用它:read_only=True    # 下面必须有一个 get_字段名 的方法对应!    authors = serializers.SerializerMethodField(read_only=True)    # post提交用这个字段~是int类型的    # get请求不要他~~设置 write_only=True    post_publish = serializers.IntegerField(write_only=True)    # post提交用这个字段~是一个ListField~列表里是数字    # get请求不要他~~设置 write_only=True    post_authors = serializers.ListField(write_only=True)    # 多对多关系查找authors用到的方法——与上面的SerializerMethodField对应    def get_authors(self,obj):        # 注意~obj是Book对象!!        # print(obj)        # 基于对象的跨表查询~注意是多个对象了~many应该设置为True        ser_obj = AuthorSerializer(obj.authors.all(),many=True)        return ser_obj.data    # POST方式增加数据需要    def create(self, validated_data):        # post提交的时候~~重写create方法        # post提交给的数据应该是这种格式的        # 注意后面那两个是post_publish、post_authors~专门用于提交的字段        """         {            "title": "西游记",            "price": 12.20,            "pub_date": "2019-12-22T10:10:11Z",            "post_publish": 1,            "post_authors": [1,2]        }        """        print('validated_data>>>',validated_data)        book_obj = models.Book.objects.create(            title=validated_data.get('title'),            price=validated_data.get('price'),            pub_date=validated_data.get('pub_date'),            publish_id=validated_data.get('post_publish'),        )        # 多对多插入数据~~基于对象的跨表查询        # 注意用set方法存多对多关系的数据        book_obj.authors.set(validated_data.get('post_authors'))        return book_obj    # PUT请求修改数据需要写的方法    def update(self, instance, validated_data):        # 如果取到了就用修改的~~如果没有就用原来的数据        instance.title = validated_data.get('title',instance.title)        instance.prince = validated_data.get('price',instance.price)        instance.pub_date = validated_data.get('pub_date',instance.pub_date)        # 上面设置了post_publish为write_only了~所以修改要用post_publish        instance.publish_id = validated_data.get('post_publish',instance.publish_id)        # 先save~然后再处理一下多对多关系的数据        instance.save()        # 基于对象的跨表查询~~注意用set方法存多对多关系的数据        # 如果没有的话需要用all方法取出所有对象~~        # # 上面设置了post_authors为write_only了~所以修改要用post_authors        instance.authors.set(validated_data.get('post_authors',instance.authors.all()))        # 最后记得把instance 返回        return instance

在DRF自带的页面进行数据的增删改查测试

至此DRF就写好了,我们可以根据路由去访问对应的页面进行数据的增删改查操作(需要注意,必须先在settings中注册了rest_framework后才能访问DRF自带的页面)

DRF自带的页面是这样的:

当然,我们不能让用户看这样的页面,这就需要前端请求DRF构建好的数据进行标签的构建了。

前端请求DRF构建好的数据并构建页面效果

测试路由如下

# 书籍展示的页面url(r'^book_list/$',views.book_list,name='book_list'),# 添加书籍的页面url(r'^add_book_view/$',views.add_book,name='add_book_view'),# 编辑书籍的展示页面~~url(r'edit_book_view/(?P
\d+)/$',views.edit_book,name='edit_book'),

视图函数如下

视图函数非常简单,再加上是进行数据测试,所以这里的视图函数只负责返回页面。

数据的操作全部是用ajax与js做的。

# 展示 书籍列表def book_list(request):    return render(request,'book_list.html')# 展示 添加书籍页面def add_book(request):    return render(request,'add_book.html')# 编辑书籍的展示页面def edit_book(request,pk):    return render(request,'edit_book.html')

所有页面的母版

{% load static %}    
{% block title %} {% endblock title %}

火之国图书管理系统

{% block pannel-body %} {% endblock pannel-body %}
{% block script %}{% endblock script %}
base.html

书籍展示页面及删除书籍的功能

书籍展示发送的是get请求。

删除书籍发送的是delete请求。

{% extends 'base.html' %}{% block title %}    主页{% endblock title %}{% block pannel-body %}    {% csrf_token %}    添加书籍    
{# 委托的父级标签用tbody #}
编号 书籍名称 价格 出版日期 出版社 作者 操作
{% endblock pannel-body %}{% block script %} {% endblock script %}

添加书籍页面

添加书籍发送的是post请求。

{% extends 'base.html' %}{% block title %}    主页{% endblock title %}{% block pannel-body %}    

添加书籍

{% endblock pannel-body %}{% block script %} {% endblock script %}

编辑书籍页面

编辑书籍这里需要说一下过程:

(1)首先我在书籍展示那里点击“编辑”的时候,先把当前点击的书籍的信息取出来,然后序列化,最后将序列化的数据存在session中。

(2)然后在编辑页面从session中获取当前需要编辑的书籍的信息并把这些信息显示在前端的input框中。

(3)最后根据用户输入的数据保存书籍信息。

{% extends 'base.html' %}{% block title %}    主页{% endblock title %}{% block pannel-body %}    

编辑书籍

{% endblock pannel-body %}{% block script %} {% endblock script %}

 

转载于:https://www.cnblogs.com/ryxiong-blog/p/11611405.html

你可能感兴趣的文章
L2-001 紧急救援 (dijkstra+dfs回溯路径)
查看>>
javascript 无限分类
查看>>
spring IOC装配Bean(注解方式)
查看>>
[面试算法题]有序列表删除节点-leetcode学习之旅(4)
查看>>
SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
查看>>
kubernetes_book
查看>>
OpenFire 的安装和配置
查看>>
侧边栏广告和回到顶部
查看>>
https://blog.csdn.net/u012106306/article/details/80760744
查看>>
海上孤独的帆
查看>>
处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Manag
查看>>
01: socket模块
查看>>
mysql触发器
查看>>
淌淌淌
查看>>
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
C++有关 const & 内敛 & 友元&静态成员那些事
查看>>
函数积累
查看>>
Swift 入门之简单语法(六)
查看>>
〖Python〗-- IO多路复用
查看>>
栈(括号匹配)
查看>>