一个比较全面的DJANGO_REST_FRAMEWORK的CASE

时间:2021-05-30 01:23:32

验证啊,过滤啊,hypermedia as the engine of ap‐plication state (HATEOAS)啊都有的。

urls.py

__author__ = 'sahara'
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register(r'sprints', views.SprintViewSet)
router.register(r'tasks', views.TaskViewSet)
router.register(r'users', views.UserViewset)

models.py

# Create your models here.

from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

class Sprint(models.Model):
    """Development iteration period."""
    name = models.CharField(max_length=100, blank=True, default='')
    description = models.TextField(blank=True, default='')
    end = models.DateField(unique=True)

    def __unicode__(self):
        return self.name or _('Sprint ending %s') % self.end

class Task(models.Model):
    """Unit of work to be done for the sprint."""
    STATUS_TODO = 1
    STATUS_IN_PROGRESS = 2
    STATUS_TESTING = 3
    STATUS_DONE = 4
    STATUS_CHOICES = (
        (STATUS_TODO, _('Not Started')),
        (STATUS_IN_PROGRESS, _('In Progress')),
        (STATUS_TESTING, _('Testing')),
        (STATUS_DONE, _('Done')),
    )
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, default='')
    sprint = models.ForeignKey(Sprint, blank=True, null=True)
    status = models.SmallIntegerField(choices=STATUS_CHOICES, default=STATUS_TODO)
    order = models.SmallIntegerField(default=0)
    assigned = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    started = models.DateField(blank=True, null=True)
    due = models.DateField(blank=True, null=True)
    completed = models.DateField(blank=True, null=True)

    def __unicode__(self):
        return self.name

forms.py

__author__ = 'sahara'
import django_filters
from .models import Task, Sprint
from django.contrib.auth import get_user_model

User = get_user_model()

class NullFilter(django_filters.BooleanFilter):
    def filter(self, qs, value):
        if value is not None:
            return qs.filter(**{'%s__isnull' % self.name: value})
        return qs

class TaskFilter(django_filters.FilterSet):
    backlog = NullFilter(name='sprint')

    class Meta:
        model = Task
        fields = ('sprint', 'status', 'assigned','backlog', )

    def __init__(self, *args, **kwargs):
        super(TaskFilter, self).__init__(*args, **kwargs)
        self.filters['assigned'].extra.update(
            {'to_field_name': User.USERNAME_FIELD}
        )

class SprintFilter(django_filters.FilterSet):
    end_min = django_filters.DateFilter(name='end', lookup_type='gte')
    end_max = django_filters.DateFilter(name='end', lookup_type='lte')

    class Meta:
        model = Sprint
        field = ('end_min', 'end_max', )

serializers.py

__author__ = 'sahara'
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework.reverse import reverse
from .models import Sprint, Task
from datetime import date
from django.utils.translation import ugettext_lazy as _

User = get_user_model()

class SprintSerializer(serializers.ModelSerializer):
    links = serializers.SerializerMethodField()

    class Meta:
        model = Sprint
        fields = ('id', 'name', 'description', 'end', 'links', )

    def get_links(self, obj):
        request = self.context['request']
        return {
            'self': reverse('sprint-detail',
                            kwargs={'pk': obj.pk}, request=request),
            'tasks': reverse('task-list',
                             request=request) + '?sprint={}'.format(obj.pk),
        }

    def validate_end(self, attrs):
        end_date = attrs
        # new = not self.object
        #changed = self.object and self.object.end != end_date
        if (end_date < date.today()):
            msg = _('End date cannot be in the past.')
            raise serializers.ValidationError(msg)
        return attrs

class TaskSerializer(serializers.ModelSerializer):
    assigned = serializers.SlugRelatedField(
        slug_field=User.USERNAME_FIELD, required=False, read_only=True, )
    status_display = serializers.SerializerMethodField()
    links = serializers.SerializerMethodField()

    class Meta:
        model = Task
        fields = ('id', 'name', 'description', 'sprint',
                  'status', 'status_display', 'order',
                  'assigned', 'started', 'due', 'completed', 'links', )
    def get_status_display(self, obj):
        return obj.get_status_display()
    def get_links(self, obj):
        request = self.context['request']
        links = {
            'self': reverse('task-detail',
                            kwargs={'pk': obj.pk}, request=request),
            'sprint': None,
            'assigned': None,
        }
        if obj.sprint_id:
            links['sprint'] = reverse('sprint-detail',
                                  kwargs={'pk': obj.sprint_id}, request=request)
        if obj.assigned:
            links['assigned'] = reverse('user-detail',
                                  kwargs={User.USERNAME_FIELD: obj.assigned}, request=request)

        return links

    def validate_sprint(self, attrs):
        sprint = attrs
        if self :
            pass
            '''
            if sprint != self.sprint:
                if self.status == Task.STATUS_DONE:
                    msg = _('Cannot change the sprint of a completed task.')
                    raise serializers.ValidationError(msg)
                if sprint and sprint.end < date.today():
                     msg = _('Cannot assign task to passed sprint')
                     raise serializers.ValidationError(msg)
            '''
        else:
            if sprint and sprint.end < date.today():
                msg = _('Cannot add tasks to past sprints.')
                raise serializers.ValidationError(msg)
        return attrs

    def validate(self, attrs):
        sprint = attrs.get('sprint')
        status = int(attrs.get('status'))
        started = attrs.get('started')
        completed = attrs.get('completed')
        if not sprint and status != Task.STATUS_TODO:
            msg = _('Backlog tasks must have "Not Started" status.')
            raise serializers.ValidationError(msg)
        if started and status == Task.STATUS_TODO:
            msg = _('Started date cannot be set for not started tasks.')
            raise serializers.ValidationError(msg)
        if completed and status != Task.STATUS_DONE:
            msg = _('Completed date cannot be set for uncompleted tasks.')
            raise serializers.ValidationError(msg)
        return attrs

class UserSerializer(serializers.ModelSerializer):
    full_name = serializers.CharField(source='get_full_name', read_only=True)
    links = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('id', User.USERNAME_FIELD, 'full_name', 'is_active', 'links', )

    def get_links(self, obj):
        request = self.context['request']
        user_name = obj.get_username()
        return {
            'self': reverse('user-detail',
                            kwargs={User.USERNAME_FIELD: user_name}, request=request),
            'tasks': '{}?assigned={}'.format(
                reverse('task-list', request=request), user_name),
        }

views.py

from django.contrib.auth import get_user_model
from rest_framework import viewsets, authentication, permissions, filters
from .forms import TaskFilter, SprintFilter
from .models import Sprint, Task
from .serializers import SprintSerializer, TaskSerializer, UserSerializer

# Create your views here.
User = get_user_model()

class DefaultsMixin(object):
    authentication_classes = (
        authentication.BasicAuthentication,
        authentication.TokenAuthentication,
    )
    permission_classes = (
        permissions.IsAuthenticated,
    )
    paginate_by = 25
    paginate_by_param = 'page_size'
    max_paginate_by = 100
    filter_backends = (
        filters.DjangoFilterBackend,
        filters.SearchFilter,
        filters.OrderingFilter,
    )

class SprintViewSet(DefaultsMixin, viewsets.ModelViewSet):
    queryset = Sprint.objects.order_by('end')
    serializer_class = SprintSerializer
    filter_class = SprintFilter
    search_fields = ('name', )
    ordering_fields = ('end', 'name', )

class TaskViewSet(DefaultsMixin, viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    filter_class = TaskFilter
    search_fields = ('name', 'description', )
    ordering_fields = ('name', 'order', 'started', 'due', 'completed', )

class UserViewset(DefaultsMixin, viewsets.ReadOnlyModelViewSet):
    lookup_field = User.USERNAME_FIELD
    lookup_url_kwarg = User.USERNAME_FIELD
    queryset = User.objects.order_by(User.USERNAME_FIELD)
    serializer_class = UserSerializer
    search_fields = (User.USERNAME_FIELD, )

截图,注意有相关链接哟。

一个比较全面的DJANGO_REST_FRAMEWORK的CASE

一个比较全面的DJANGO_REST_FRAMEWORK的CASE

一个比较全面的DJANGO_REST_FRAMEWORK的CASE

一个比较全面的DJANGO_REST_FRAMEWORK的CASE

一个比较全面的DJANGO_REST_FRAMEWORK的CASE的更多相关文章

  1. 一个比较全面的java随机数据生成工具包

    最近,由于一个项目的原因需要使用一些随机数据做测试,于是写了一个随机数据生成工具,ExtraRanom.可以看成是Java官方Random类的扩展,主要用于主要用于测试程序.生成密码.设计抽奖程序等情 ...

  2. 最全面的 C&plus;&plus; 资源、框架大全

    转载自   http://www.codeceo.com/article/cpp-resource-framework.html#0-tsina-1-99850-397232819ff9a47a7b7 ...

  3. &lbrack;转&rsqb;一篇很全面的freemarker教程

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  4. 一篇很全面的freemarker教程

    以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成:1,文本:直接输出的部分2,注释:<#-- ... --& ...

  5. 【转】一篇很全面的freemarker教程---有空慢慢实践

    FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输 ...

  6. 一篇很全面的freemarker教程 前端工程师必备

    FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输 ...

  7. 干货&comma;比较全面的c&num;&period;net公共帮助类

    比较全面的c#帮助类 比较全面的c#帮助类,日常工作收集,包括前面几家公司用到的,各式各样的几乎都能找到,所有功能性代码都是独立的类,类与类之间没有联系,可以单独引用至项目,分享出来,方便大家,几乎都 ...

  8. 转:一篇很全面的freemarker教程

    最近在使用freemarker,于是在网上找了一些教程学习,如下: 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组 ...

  9. 最全面的 Android 编码规范指南

    最全面的 Android 编码规范指南 本文word文档下载地址:http://pan.baidu.com/s/1bXT75O 1. 前言 这份文档参考了 Google Java 编程风格规范和 Go ...

随机推荐

  1. 【转】el表达式的判断符

    el表达式一般不直接用==判断是否相等 != > < >= <=之类的表示不等于 大于 小于 大于等于 小于等于,而是使用字母表示的表达式,他们的表示如下: == eq 等于 ...

  2. hdu 1166 敌兵布阵(树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始 ...

  3. Fiddler进行模拟Post提交json数据,总为null解决方式

    Request Headers: User-Agent: FiddlerHost: localhost:3248Content-Type: application/json; charset=utf- ...

  4. 避免重定向301&amp&semi;302 &lpar;Avoid Redirects&rpar;

    这个也是Best Practices for Speeding Up Your Web Site的第12条原则: 重定向的意思是,用户的原始请求(例如请求A)被重定向到其他的请求(例如请求B).这是H ...

  5. JQuery之正则表达式

    1.定义正则表达式 /.../  用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m 表示多行匹配 2.匹配正则表达式 非全局模式,不分组 var patte ...

  6. setInterval和setTimeout调用方法小知识科普

    function a() { alert('hello'); } setInterval(a, ); setInterval(a(), ); setInterval(); setInterval(); ...

  7. 废旧鼠标先别丢,用来学习nRF52832 的QDEC

    刚发现nRF52832有一个 QDEC,SDK13.0中还有驱动,但是不太友好.  如果大家有废旧鼠标,建议拆一个编码器下来“学习”.鼠标的一般原理如下: 图一 图中那个SW4 ALPS EC10E  ...

  8. 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度

    题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...

  9. PARTITION RANGE ALL 的优化

    建议如下: 检查数据库的cpu 消耗 ,Sql_id :***** 消耗过多资源,这个新上线sql, 20号才上线,是对log 进行分析,平均每次执行时间300s.,使用的是PARTITION RAN ...

  10. 如何计算CDS view里两个时间戳之间的天数间隔

    ABAP透明表里的时间戳,数据类型为dec: 有个需求:计算这两个时间戳之间的天数间隔,丢弃时间戳年-月-日8位后面的小时:分钟:秒. 举个例子:如果时间戳是20180918173132,丢弃1731 ...

相关文章