将自定义查询集传递给Django Rest Framework中的序列化程序

ako*_*ian 9 python django django-rest-framework

我正在使用Django rest framework 2.3我有一个这样的类

class Quiz():
    fields..

# A custom manager for result objects
class SavedOnceManager(models.Manager):                                                                                                                                                                                                
    def filter(self, *args, **kwargs):
        if not 'saved_once' in kwargs:
            kwargs['saved_once'] = True
        return super(SavedOnceManager, self).filter(*args, **kwargs)

class Result():
    saved_once = models.NullBooleanField(default=False, db_index=True,
                                         null=True)
    quiz = models.ForeignKey(Quiz, related_name='result_set')

    objects = SavedOnceManager()
Run Code Online (Sandbox Code Playgroud)

如您所见,我在结果上有自定义管理器,因此Result.objects.filter()只返回save_once设置为True的结果

现在我的Serializers看起来像这样:

class ResultSerializer(serializers.ModelSerializer):                                                                                                                                                                                                    
      fields...

class QuizSerializer(serializers.ModelSerializer):                                                                                                                                                                                                      
    results = ResultSerializer(many=True, required=False, source='result_set')
Run Code Online (Sandbox Code Playgroud)

现在,如果我序列化我的测验,它将只返回已saved_once设置的结果True.但对于特定用例,我希望序列化程序返回所有对象.我已经读过,我可以通过传递一个queryset参数http://www.django-rest-framework.org/api-guide/relations/(进一步注释部分)来做到这一点.但是,当我尝试这个

results = ResultSerializer(many=True, required=False, source='result_set',
                           queryset=
                               Result.objects.filter(
                               saved_once__in=[True, False]))
Run Code Online (Sandbox Code Playgroud)

我得到TypeError: __init__() got an unexpected keyword argument 'queryset' 并查看DRF的源代码(在我的版本至少)它不接受queryset参数.

寻找一些指导,看看这是否可能......谢谢!

Mar*_*way 8

在我看来,修改这样的过滤器不是一个很好的做法.如果在没有发生额外过滤的情况下无法在Result模型上使用过滤器,那么很难为您编写解决方案.我建议不要以这种方式修改过滤器,而是创建一个自定义管理器方法,允许您以明显的方式应用过滤器,例如/

class SavedOnceManager(models.Manager):                                                                                                                                                                                                
    def saved_once(self):
        return self.get_queryset().filter('saved_once'=True)
Run Code Online (Sandbox Code Playgroud)

因此,您可以按预期查询saved_once行或未过滤的行:

Results.objects.all()
Results.objects.saved_once().all()
Run Code Online (Sandbox Code Playgroud)

以下是一种可以在序列化程序中使用其他查询集的方法.但是,在我看来,如果默认管理器以某种方式过滤掉saved_once对象,那么这很可能不会对你有用.因此,你的问题在于其他地方.

class QuizSerializer(serializers.ModelSerializer):  
    results = serializers.SerializerMethodField()

    def get_results(self, obj):
        results = Result.objects.filter(id__in=obj.result_set)
        return ResultSerializer(results, many=True).data
Run Code Online (Sandbox Code Playgroud)