一.在开发某运动app时,遇见以下情况

  1.部分表内容如下:

class Sports(models.Model):
'''
运动表
'''
school = models.ForeignKey(Schools, verbose_name='学校', on_delete=models.CASCADE)
sport_name = models.CharField(max_length=30, verbose_name='运动项目')
image = models.ImageField(upload_to='sports/%Y/%m', verbose_name='运动封面图')
add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') class Meta:
verbose_name = '运动项目'
verbose_name_plural = verbose_name
unique_together = ('school', 'sport_name') def __str__(self):
return self.sport_name
class Schedule(models.Model):
'''
发起约运动
'''
Status = ((1, '已完成'), (2, '待人加入'), (3, '已取消'))
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name='发起人')
join_type = models.BooleanField(verbose_name='是否发起人')
now_people = models.IntegerField(verbose_name='已有人数', null=True, blank=True)
school = models.ForeignKey(Schools, on_delete=models.CASCADE, verbose_name='学校', default='')
sport = models.ForeignKey(Sports, on_delete=models.CASCADE, verbose_name='运动项目')
address = models.CharField(verbose_name='约定地点', max_length=100)
sport_time = models.DateTimeField(verbose_name='约定运动开始时间')
sport_end_time = models.DateTimeField(verbose_name='约定运动结束时间', default='')
people_nums = models.IntegerField(verbose_name='人数')
add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
status = models.IntegerField(choices=Status, verbose_name='状态') class Meta:
verbose_name = '发起约运动'
verbose_name_plural = verbose_name def __str__(self):
return self.sport.sport_name + '-' + str(self.sport_time)
class UserProfile(AbstractUser):
'''
用户表
'''
name = models.CharField(max_length=30, null=True, blank=True, verbose_name='姓名')
image = models.ImageField(upload_to='users/', default='', null=True, blank=True, verbose_name='头像')
birthday = models.DateField(null=True, blank=True, verbose_name='出生年月')
mobile = models.CharField(max_length=11, verbose_name='电话', null=True, blank=True)
student_id = models.CharField(max_length=32, verbose_name='学号', default='', null=True, blank=True)
gender = models.CharField(max_length=6, choices=(('male', '男'), ('fmale', '女')), default='男', verbose_name='性别')
email = models.EmailField(verbose_name='邮箱')
school = models.ForeignKey(Schools, verbose_name='学校', on_delete=models.CASCADE)
institude = models.ForeignKey(Schools, verbose_name='学院', on_delete=models.CASCADE, related_name='institude')
profession = models.ForeignKey(Schools, verbose_name='专业', on_delete=models.CASCADE, related_name='profession')
add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') class Meta():
verbose_name = '用户'
verbose_name_plural = verbose_name def __str__(self):
if self.name:
return self.name
else:
return self.username class Schedule(models.Model):
'''
发起约运动
'''
Status = ((1, '已完成'), (2, '待人加入'), (3, '已取消'))
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name='发起人')
join_type = models.BooleanField(verbose_name='是否发起人')
now_people = models.IntegerField(verbose_name='已有人数', null=True, blank=True)
school = models.ForeignKey(Schools, on_delete=models.CASCADE, verbose_name='学校', default='')
sport = models.ForeignKey(Sports, on_delete=models.CASCADE, verbose_name='运动项目')
address = models.CharField(verbose_name='约定地点', max_length=100)
sport_time = models.DateTimeField(verbose_name='约定运动开始时间')
sport_end_time = models.DateTimeField(verbose_name='约定运动结束时间', default='')
people_nums = models.IntegerField(verbose_name='人数')
add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')
status = models.IntegerField(choices=Status, verbose_name='状态') class Meta:
verbose_name = '发起约运动'
verbose_name_plural = verbose_name def __str__(self):
return self.sport.sport_name + '-' + str(self.sport_time)

  2.序列化想实现的功能:

    在序列化Schedule表时,sport是一个外键字段,想筛选sport的外键school是当前已登录的用户的school字段下的该学校所有运动项目(即筛选为queryset=Sports.objects.filter(school=user.school)),看似很简单,但该如何在字段中获取当前用户呐。

    首先想到,把该字段设计为SerializerMethodField字段,即如下(该方法确实能实现筛选,但这不是我要的结果,我想在序列化时有该字段,并且能选择筛选出的数据中的一个并添加新的数据):

#失败方法
sport = serializers.SerializerMethodField()
def get_sport(self, obj):
all_sport = Sports.objects.filter(school=self.context['request'].user.school).values_list('pk',flat=True)
json_all = SportsSerializer(all_sport, many=True,
context={'request': self.context['request']}).data
return all_sport

    然后就有点麻烦,想从写view中的get_queryset(),也是只能在list或retrieve中才能筛选,而序列化添加仍是一个问题;又想到从写一个类或者函数专门筛选,但是又增大了获取当前用户的难度,有点恼火,咋办,看看源码它写了哪些方法,真看不太懂,只能了解一点。

    看到了RelatedField中的get_queryset()方法,好像重写它有点作用:

 def get_queryset(self):
queryset = self.queryset
if isinstance(queryset, (QuerySet, Manager)):
# Ensure queryset is re-evaluated whenever used.
# Note that actually a `Manager` class may also be used as the
# queryset argument. This occurs on ModelSerializer fields,
# as it allows us to generate a more expressive 'repr' output
# for the field.
# Eg: 'MyRelationship(queryset=ExampleModel.objects.all())'
queryset = queryset.all()
return queryset

三.目前最终方案:

    于是勉强写吧,重写该方法确实有用,只能说功能完成了,但还真得改进:

 class SportPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
def get_queryset(self):
queryset = self.queryset
# if isinstance(queryset, (QuerySet, Manager)):
# Ensure queryset is re-evaluated whenever used.
# Note that actually a `Manager` class may also be used as the
# queryset argument. This occurs on ModelSerializer fields,
# as it allows us to generate a more expressive 'repr' output
# for the field.
# Eg: 'MyRelationship(queryset=ExampleModel.objects.all())'
queryset = queryset.filter(school=self.context['request'].user.school)
return queryset sport = SportPrimaryKeyRelatedField(queryset=Sports.objects.all(), label="运动")

    

django restframework PrimaryKeyRelatedField筛选的困惑的更多相关文章

  1. django restframework serializer 增加自定义字段

    在使用django restframework serializer 序列化在django中定义的model时,有时候我们需要额外在serializer中增加一些model中没有的字段.有两种方法实现 ...

  2. django restframework 的日常使用

    本文讨论 django restframework 的日常使用,满足常用 api 编写的需求,比如 List, Detail, Update, Put, Patch 等等.探讨 django rest ...

  3. django restframework

    一.django restframework 请求流程源码剖析 上面的认证一个流程是rest_framework的关于APIauth的认证流程,,这个流程试用权限.频率.版本.认证.这个四个组件都是通 ...

  4. django restframework jwt

    既然要来学习jwt(json web token),那么我们肯定是先要了解jwt的优势以及应用场景--跨域认证. $ pip install djangorestframework-jwt 传统coo ...

  5. django restframework 快速入门

    django restframework 快速入门 基本流程 建立 Models 依靠 Serialiers 将数据库取出的数据 Parse 为 API 的数据(可用于返回给客户端,也可用于浏览器显示 ...

  6. Django Restframework 实践(一)

    具备以下知识: django http://www.cnblogs.com/menkeyi/p/5882464.html http://www.cnblogs.com/menkeyi/p/588245 ...

  7. django: rest-framework的 分页和过滤

    django: rest-framework的 分页和过滤 2018年06月28日 10:09:01 weixin_42359464 阅读数:136 标签: flaskrestframeworkdja ...

  8. Django RestFramework (DRF)

    准备: 下载 pip install djangorestframework 一 APIView源码解析 1 预备知识 CBV(class based view)FBV(function based ...

  9. 测开大佬告诉你:如何5分钟快速创建restful风格的API接口-使用django restframework框架

    一.思考❓❔ 1.创建API接口难吗? 软件测试工程师: 只测过API接口, 从没创建过 应该需要掌握一门后端开发语言和后端开发框架吧!? 脑容量有限,想想就可怕 2.如何创建API接口呢? 使用Dj ...

随机推荐

  1. 通过JS如何获取IP地址

    通过JS获取你真实的外网IP和内网IP,就算开代理也没有用,想想真是太可怕了,还能不能愉快的装逼了! 代码: //get the IP addresses associated with an acc ...

  2. ④---在Eclipse中导入GIT项目

    Eclipse中导入GIT项目 以下将为大家介绍如何在Eclipse中导入GIT项目. 一.在Eclipse中安装GIT 1首先打开Eclipse,然后点击Help>Install New So ...

  3. KNN-笔记(1)

    1 - 背景 KNN:k近邻,表示基于k个最近的邻居的一种机器学习方法.该方法原理简单,构造方便.且是一个非参数化模型. KNN是一个"懒学习"方法,也就是其本身没有训练过程.只有 ...

  4. 实现RunOnUiThread和RunOnUiThreadBlock

    现在需要实现一个工具类,RunUtils,这个类中包含runOnUiThread(Context context, Runnable runnable)和runOnUiThreadBlock(Cont ...

  5. mybatis抽取出的工具-(一)通用标记解析器(即拿即用)

    目录 1. 简介 1.1 mybatis-config.xml 中使用 1.2 xxxMapper.xml 中使用 2. 原理 2.1 GenericTokenParser 成员变量 2.2 Gene ...

  6. 使用 IIS 在 Windows 上托管 ASP.NET Core2.0

    准备: 操作系统:Windows Server 2008 R2 或更高版本 开发环境:VS2017 第一步:新建项目ASP.NET Core Web应用程序 在 Visual Studio 中,选择“ ...

  7. 简单的将Excel数据同步到SqlServer数据库中

    1.创建一个WinForm程序,添加一个Button控件 2.Button事件 private void button1_Click(object sender, EventArgs e) { Sys ...

  8. c++构造函数成员初始化中赋值和初始化列表两种方式的区别

    先总结下: 由于类成员初始化总在构造函数执行之前 1)从必要性: a. 成员是类或结构,且构造函数带参数:成员初始化时无法调用缺省(无参)构造函数 b. 成员是常量或引用:成员无法赋值,只能被初始化 ...

  9. P66 整环的零元

    R/I=0的零因子是0+I吗? 如果不是,那请问R/I的零因子是什么呢? R/I没有零因子 R/I的零元 是I中的元素定义的等价类 么  a是理想I的元素,自然也是R的元素

  10. Redis集群搭建过程

    我在搭建Redis集群过程中遇到了一些问题,现记录下来. Redis搭建需要在系统中安装好ruby.gem.zlib等工具,可参考https://www.cnblogs.com/wuxl360/p/5 ...