Django RESTFramework——更新資料 (5)

RomanceSky發表於2018-06-01

完整例項

專案結構
    Floral
        Floral
        accounts
        manage.py
Floral/urls.py
from django.conf.urls import url, include
from rest_framework import routers
from accounts import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'ips', views.IpViewSet)
router.register(r'comments', views.CommentViewSet)

Floral/accounts/models.py
from django.db import models

# Create your models here.
from django.contrib.auth.models import AbstractBaseUser

from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _

class MyUsers(models.Model):
    #REQUIRED_FIELDS = ('name',)
    #USERNAME_FIELD = ('name')
    groups = models.ForeignKey(
        'Groups',
        null=False,
        blank=False,
        related_name='myusers',
        on_delete=models.CASCADE
    )
    name = models.CharField(
        null=False,
        blank=False,
        max_length=125,
    )
    email = models.EmailField(
        null=False,
        blank=False,
        max_length=125,
    )

    url = models.URLField(
        null=False,
        blank=True,
        max_length=125,
    )


class Groups(models.Model):
    name = models.CharField(
        null=False,
        blank=False,
        max_length=125,
    )

    url = models.URLField(
        null=False,
        blank=True,
        max_length=125,
    )

class Ip(models.Model):
    user = models.ForeignKey(
        'MyUsers',
        null=False,
        blank=False,
        related_name='ips',
        on_delete=models.CASCADE
    )
    group = models.ForeignKey(
        'Groups',
        null=False,
        blank=True,
        related_name='ips',
        on_delete=models.CASCADE
    )
    ip_addr = models.GenericIPAddressField(
        blank=False,
        null=False,
    )

class Comment(models.Model):
    email = models.EmailField(
        null=False,
        blank=False,
        max_length=125,
    )
    content = models.CharField(
        null=False,
        blank=False,
        max_length=200,
    )

    created = models.DateTimeField(
        help_text=_('date'),
        auto_now_add=True
    )

    user = models.ForeignKey(
        'MyUsers',
        null=False,
        blank=False,
        related_name='comments',
        on_delete=models.CASCADE
    )


Floral/accounts/views.py
from django.shortcuts import render
# Create your views here.
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from accounts.serializers import UserSerializer, GroupSerializer, IpSerializer, CommentSerializer
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from knox.auth import TokenAuthentication
from knox.models import AuthToken
from rest_framework.permissions import IsAuthenticated, AllowAny
from accounts.models import Ip, Comment

class GroupViewSet(viewsets.ModelViewSet):
    """
    允許組檢視或編輯的API路徑。
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer

class IpViewSet(viewsets.ModelViewSet):
    """
    允許組檢視或編輯的API路徑。
    """
    queryset = Ip.objects.all()
    serializer_class = IpSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

Floral/accounts/serializers.py
from django.contrib.auth.models import User, Group
from rest_framework import serializers
from accounts.models import Ip
from rest_framework.response import Response

from datetime import datetime
from rest_framework.renderers import  JSONRenderer
from rest_framework.parsers import JSONParser
from django.utils.six import BytesIO


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups', 'user')


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')


class IpSerializer(serializers.HyperlinkedModelSerializer):
    #SerializerMethodField(): Serialization and deserialization
    group = serializers.SerializerMethodField()
    user = serializers.SerializerMethodField()

    class Meta:
        model = Ip
        fields = ('user',  'ip_addr', 'group')

    def get_group(self, obj):
        group = obj.group
        return{'url': group.url,
               'name': group.name,
              }

    def get_user(self, obj):
        user = obj.user
        if user:
            print(1)
        return {
            'name': user.name + ' ' + 'hello'
        }

    def get_attribute(self, instance):
        a = instance
        print(a)
        return instance


class Comment(object):
    def __init__(self, email, content, created=None):
        self.email = email
        self.content = content
        self.created = created or datetime.now()

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
    
    def create(self, validated_data):
        return Comment(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance

comment = Comment('1111@qq.com', content='foo bar')
serializer = CommentSerializer(comment)
s = serializer.data
json = JSONRenderer().render(s)

stream = BytesIO(json)
data = JSONParser().parse(stream)
print(data)
serializer = CommentSerializer(data=data)
serializer.is_valid()
k = serializer.validated_data
print(k)

複製程式碼

訪問http://127.0.0.1:8000/comments/1/

PATCH http://127.0.0.1:8000/comments/1/ 更新部分資料(可以是單條資料) 對應於drf中的update方法

具體的HTTP方法和drff中的操作對應關係參考https://www.jianshu.com/p/69bdfc531f48

使用postman測結果

https://note.youdao.com/yws/res/32204/WEBRESOURCE57124744967a96fa0af039a2aff731a3

如果Comment是一個模型Model

    def create(self, validated_data):
        return Comment(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance
可以更改為

    def create(self, validated_data):
        return Comment.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        instance.save()
        return instance

如果你的物件例項對應Django的模型,你還需要確保這些方法將物件儲存到資料庫。
例如,如果Comment是一個Django模型的話。
【Django rest framework 官方文件解釋】
複製程式碼

相關文章