• DRF 有无外键操作实例


    • models.py
    from django.db import models
    
    # Create your models here.
    class Category(models.Model):
        """
        文章分类
        """
        name = models.CharField(verbose_name='分类',max_length=32)
    
    class Article(models.Model):
        """
        文章表
        """
        status_choices = (
            (1,'发布'),
            (2,'删除'),
        )
        title = models.CharField(verbose_name='标题',max_length=32)
        summary = models.CharField(verbose_name='简介',max_length=255)
        content = models.TextField(verbose_name='文章内容')
        cates = models.ForeignKey(to='Category',verbose_name="文章类别",null=True,blank=True)
        status = models.IntegerField(verbose_name='状态', choices=status_choices, default=1)
        tag = models.ManyToManyField(verbose_name='标签', to='Tag', null=True, blank=True)
    
    class Tag(models.Model):
        """标签"""
        title = models.CharField(verbose_name='标签',max_length=32)
    
    • Urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^drf/category/$', views.DrfCategoryView.as_view()),
        url(r'^drf/category/(?P<pk>d+)/$', views.DrfCategoryView.as_view()),
        url(r'^new/category/$', views.NewDrfCategory.as_view()),
        url(r'^new/category/(?P<pk>d+)/$', views.NewDrfCategory.as_view()),
        url(r'^drf/article/$', views.DrfArticle.as_view()),
        url(r'^drf/article/(?P<pk>d+)/$', views.DrfArticle.as_view()),
    ]
    
    • Views.py
    # 无外键的表进行增删改查
    
    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from api import models
    from django.forms.models import model_to_dict
    from rest_framework import serializers
    
    class NewCategorySerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Category
            fields = '__all__'
    
    class NewDrfCategory(APIView):
    
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if not pk:
                queryset = models.Category.objects.all()
                ser = NewCategorySerializer(instance=queryset, many=True)
                return Response(ser.data)
            else:
                queryset = models.Category.objects.filter(id=pk).first()
                ser = NewCategorySerializer(instance=queryset, many=False)
                return Response(ser.data)
    
        def post(self, request, *args, **kwargs):
            ser = NewCategorySerializer(data=request.data)
            if ser.is_valid():		# 数据校验和modelform类似
                ser.save()				# 返回值为保存的数据对象;括号里也可以添加键值对,可以指定字段。
                return Response('ok')
            else:
                return Response(ser.errors)
    
        def put(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            queryset = models.Category.objects.filter(id=pk).first()
            ser = NewCategorySerializer(instance=queryset, data=request.data)
            if ser.is_valid():
                ser.save()
                return Response('ok')
            else:
                return Response(ser.errors)
    
        def delete(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            models.Category.objects.filter(id=pk).delete()
            return Response('ok')
          
    
    # 有外键的表增删改查
    
    class ArticleSerializer(serializers.ModelSerializer):
        ### 第一种可以获取外键关联表数据的方法 ####
        # 无choices选择的字段
        cates_name = serializers.CharField(source='cates.name', required=False)
    
        # 有choices选择的字段
        article_status = serializers.CharField(source='get_status_display', required=False)
        # 名称如果和字段名称一样,会覆盖从数据库中获取的数据;当前端提交数据的时候会出问题,这时可以定义两个类分开进行查询和存储提交的数据。
        # required=False:是否需要,False表示在接收添加数据时不会对这个字段进行检查
    
        ### 第二种可以获取外键关联表数据的方法 ####
        aa = serializers.SerializerMethodField()
        bb = serializers.SerializerMethodField()
        tag_info = serializers.SerializerMethodField()
    
        class Meta:
            model = models.Article
            # fields = '__all__' 	# 包含上面自定义的获取外键的字段
            fields = ('id','title','summary','content','cates','cates_name','status','article_status','aa','bb','tag_info')
            # depth = 1         # 查询外键关联的表的所有字段数据,数字1表示查询到1层关联表,最大为10.
    
        ### 如果要采用第二种方法,必须按照下面的格式写。
        def get_aa(self,obj):
            return obj.cates.name
    
        # 针对有choices选择的字段
        def get_bb(self,obj):
            return obj.get_status_display()
    
        ## 针对ManyToManyField关系的字段
        def get_tag_info(self,obj):
            tag_list = [{"id":tag_msg.id,"title":tag_msg.title} for tag_msg in obj.tag.all()]
            return tag_list
    
    
    class DrfArticle(APIView):
    
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if not pk:
                queryset = models.Article.objects.all()
                ser = ArticleSerializer(instance=queryset, many=True)
                return Response(ser.data)
            else:
                queryset = models.Article.objects.filter(id=pk).first()
                ser = ArticleSerializer(instance=queryset, many=False)
                return Response(ser.data)
    
        def post(self, request, *args, **kwargs):
            ser = ArticleSerializer(data=request.data)
            if ser.is_valid():
                ser.save()
                return Response('ok')
            else:
                return Response(ser.errors)
    
        def put(self, request, *args, **kwargs):
            """
            全部更新,需要提交所有字段的数据
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            pk = kwargs.get('pk')
            queryset = models.Article.objects.filter(id=pk).first()
            ser = ArticleSerializer(instance=queryset, data=request.data)
            if ser.is_valid():
                ser.save()
                return Response('ok')
            else:
                return Response(ser.errors)
    
        def patch(self, request, *args, **kwargs):
            """
            局部更新,只需要提交需要修改的字段数据即可
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            pk = kwargs.get('pk')
            queryset = models.Article.objects.filter(id=pk).first()
            ser = ArticleSerializer(instance=queryset, data=request.data,partial=True)  # partial=True 是否开启局部更新
            if ser.is_valid():
                ser.save()
                return Response('ok')
            else:
                return Response(ser.errors)
    
  • 相关阅读:
    jQuery诞生记-原理与机制
    你所不知的 CSS ::before 和 ::after 伪元素用法
    http中get与post的区别
    Http请求方法
    TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
    TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
    TCP/IP详解学习笔记(2)-数据链路层
    TCP/IP详解学习笔记(1)-基本概念
    全面解析Java的垃圾回收机制
    深入Java虚拟机:JVM中的Stack和Heap
  • 原文地址:https://www.cnblogs.com/os-linux/p/11815360.html
Copyright © 2020-2023  润新知