一个比较全面的DJANGO_REST_FRAMEWORK的CASE
验证啊,过滤啊,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的更多相关文章
- 一个比较全面的java随机数据生成工具包
最近,由于一个项目的原因需要使用一些随机数据做测试,于是写了一个随机数据生成工具,ExtraRanom.可以看成是Java官方Random类的扩展,主要用于主要用于测试程序.生成密码.设计抽奖程序等情 ...
- 最全面的 C++ 资源、框架大全
转载自 http://www.codeceo.com/article/cpp-resource-framework.html#0-tsina-1-99850-397232819ff9a47a7b7 ...
- [转]一篇很全面的freemarker教程
copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...
- 一篇很全面的freemarker教程
以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成:1,文本:直接输出的部分2,注释:<#-- ... --& ...
- 【转】一篇很全面的freemarker教程---有空慢慢实践
FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输 ...
- 一篇很全面的freemarker教程 前端工程师必备
FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... -->格式部分,不会输 ...
- 干货,比较全面的c#.net公共帮助类
比较全面的c#帮助类 比较全面的c#帮助类,日常工作收集,包括前面几家公司用到的,各式各样的几乎都能找到,所有功能性代码都是独立的类,类与类之间没有联系,可以单独引用至项目,分享出来,方便大家,几乎都 ...
- 转:一篇很全面的freemarker教程
最近在使用freemarker,于是在网上找了一些教程学习,如下: 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组 ...
- 最全面的 Android 编码规范指南
最全面的 Android 编码规范指南 本文word文档下载地址:http://pan.baidu.com/s/1bXT75O 1. 前言 这份文档参考了 Google Java 编程风格规范和 Go ...
随机推荐
- 【转】MySQL的安装与配置
一.MySQL的安装 1.在线安装: 命令:sudo apt-get install mysql-server 在安装的过程中将提示为“root”用户设置密码,输入自己的密码即可,安装按成后已自动配置 ...
- JAVA生成EXCEL图表
跟据客户的要求,需要开发一套包括图形的报表,还需要导出WORD 图表需要这样: 这样: 这样: 还有这样: 接下来是实现思路: 以往用的最多的就是JFreechart,手上也有实现各种图形的资源,但是 ...
- 老老实实学WCF[第一篇] Hell wcf
老老实实学WCF 第一篇 Hello WCF WCF(Windows Communication Foundation)是微软公司推出的面向服务技术的集大成者,涵盖继承了其之前发布的所有的分布式应用 ...
- Oracle常见的问题
1.oracle 中文问号乱码解决方法: 在系统变量里面添加变量名:NLS_LANG 变量值: SIMPLIFIED CHINESE_CHINA.ZHS16GBK 2.查询oracle 里的主键 S ...
- Ubuntu 截屏
一个图说明: 系统设置->键盘->快捷键->屏幕截图 里面可以查看及修改快捷键
- python 自动化之路 day 00 目录
目录 初识Python Python基本数据类型 Python基础之函数 Python基础之杂货铺 模块 面向对象 网络编程 HTML CSS JavaScript DOM jQuery Web框架本 ...
- js优化 ----js的有序加载
说到有序加载,我们先来说说js的无序加载: <script src="jquery/jquery-1.4.1.js" type="text/javascript&q ...
- 【Qt】数据库连接池
请查看公孙二狗的文章 数据库连接池
- 用phpmailer发邮件 中文乱码问题解决
加入如下代码解决. $mail->CharSet = "GB2312"; //utf-8; $mail->Encoding = "base64"; ...
- Delphi Base64 编解码函数
Delphi 自带 Base64 编解码的单元, EncdDecd这个单元提供两套四个公开函数: 对流的编解码:procedure EncodeStream(Input, Output: TStrea ...