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)
相關文章
相關標籤/搜索