一个比较全面的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 ...
随机推荐
- JavaScript学习笔记(10)——JavaScript语法之操作DOM
1.页面输出用document.write()方法,但是不可以在window.onload中用,否则整个html页面将被覆盖. 2.通过javascript获取对象后,改变对象中的html内容:doc ...
- C++记录2
1, 求成员变量的偏移: 2, const实现机制:在编译期间完成,对于内置类型,如int, 编译器可能使用常数直接替换掉对此变量的引用.而对于结构体不一定. 编译器在优化代码时把j直接优化成64h了 ...
- [摘抄] 为什么 Linq 可以高效率查询 SQL ?
From C# in Depth(3rd) - Jon Skeet using (LinqDemoDataContext db = new LinqDemoDataContext()) { var f ...
- aws linuxbrew GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2
在 aws ec2 里面出现 segement fault,ls rm 等命令都不能正常运行,会出现: ls: relocation error: /home/ec2-user/.linuxbrew/ ...
- CSS3中的变形处理(transform)属性
在CSS3中,可以利用transform功能来实现文字或图像的旋转.扭曲.缩放.位移.矩阵.原点这六种类型的变形处理,下面将详细讲解transform的使用. 变形--旋转 rotate() div. ...
- @+id/和android:id的区别
android:id="@+id/btn",表示在R.java文件里面新增一个id为btn的控件索引,最常用的一种声明控件id的方式.android:id="@andro ...
- 排序,求几个最值问题,输入n个整数,输出其中最小的k个元素。
看完两个求最大值算法之后的一些感想. 如果想直接看算法的可以跳过.但是我觉得我这些想法还是比较有用的,至少对我将来的算法设计是这样的. 算法的功能越强大,必然意味着速度慢,因为根据丛林法则,那种慢又功 ...
- sublime 修改Xdebug插件快捷键
最近在用Xdebug插件 感觉挺好用 但是快捷键不太舒服,特别是调试下一步的时候,比较麻烦,按键较多: 所以想DIY下 但是preferences->package setting ->X ...
- php入门常量
常量像变量一样,用于临时存储一个值,但是常量在许多方面与变量不同. 常量:1.是在程序执行期间无法改变数据,常量的作用域是全局的.2.常量的命名与与变量相似,只是不带美元符号“$”.一个有效的常量名由 ...
- python基础教程笔记—即时标记(详解)
最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习py ...