Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将用户凭据从Tastypie传递到Django模型_Python_Django_Tastypie - Fatal编程技术网

Python 将用户凭据从Tastypie传递到Django模型

Python 将用户凭据从Tastypie传递到Django模型,python,django,tastypie,Python,Django,Tastypie,我在Django Tastypie中使用自定义身份验证,当身份验证成功时,它将返回用户名和密码。在ModelResource实例中,身份验证成功后,用户名和密码可用: class TestResource(ModelResource): class Meta: queryset = Test.remote_supported.get_all(username,password) resource_name = 'test' filteri

我在Django Tastypie中使用自定义身份验证,当身份验证成功时,它将返回用户名和密码。在ModelResource实例中,身份验证成功后,用户名和密码可用:

class TestResource(ModelResource):

    class Meta:
        queryset = Test.remote_supported.get_all(username,password)
        resource_name = 'test'
        filtering = {
            'id' : ALL,
        }
        detail_allowed_methods = ['get', 'post', 'patch']       
        authorization = Authorization()
        authentication = MyCustomAuth()
        always_return_data = True

    def __init__(self, api_name=None):
        self.username = None
        self.password = None
        super(TestResource, self).__init__(api_name)

    def is_authenticated(self, request):
        auth_result = self._meta.authentication.is_authenticated(request)

        if isinstance(auth_result, HttpResponse):
            raise ImmediateHttpResponse(response=auth_result)

        if not auth_result is True:
            raise ImmediateHttpResponse(response=http.HttpUnauthorized())

        # this is where I receive the username and password from my custom auth
        self.username, self.password = self._meta.authentication.get_credentials()
这段代码显然不起作用,因为那个用户名和密码在元类中不可用,即使是,更改它也不会影响这个实例,而是所有实例,这不是我的意图,因为用户名和密码的范围应该是每个RESTful查询

这就是我的模型的样子:

class RemoteAuthSupported(models.Manager):
    def get_all(self, username, password):
        # ... here I do some custom operations with the username and password
        return super(RemoteAuthSupported, self).get_query_set()  

class Test(models.Model):
    objects = models.Manager()
    remote_supported = RemoteAuthSupported()

    # ... the field declarations follow here ... #

我尝试这样做的原因是,我在Django应用程序中使用了一个非ORM数据源,它需要自己的身份验证,但用户名和密码相同。处理此参数从Tastypie ModelResource传递到Django模型的方法是什么?我可能应该在这里提到,没有使用任何用户模型。

您可以做的是覆盖返回请求资源列表的
obj\u get\u list
方法。此外,您还可以将用户名和密码设置为
请求
对象本身,以便将参数带入请求-响应路径。此外,还需要将
queryset
设置为
all()

或者反过来,您可以添加自定义授权来过滤对象列表。
请求
属性部分仍然有效

class MyAuth(Authorization):
   def authorized_read_list(self, objects, bundle):
       request = bundle.request
       return objects.get_all(request.username, request.password)
如果您更愿意使用
get\u all
模拟
queryset
,而不仅仅是交替列表端点,那么您可以覆盖
get\u object\u list

def get_object_list(self, request):
    original = super(TestResource, self).get_object_list(request)
    return original.get_all(request.username, request.password)

我查看了Tastype文档,似乎以下内容可以作为一个解决方案,尽管是业余的:

class TestResource(ModelResource):

    class Meta:
        queryset = Test.remote_supported.get_all('dummyusername','dummypassword')
        resource_name = 'test'
        filtering = {
            'id' : ALL,
        }
        detail_allowed_methods = ['get', 'post', 'patch']       
        authorization = Authorization()
        authentication = MyCustomAuth()
        always_return_data = True

    def get_object_list(self, request):
        """
        This method calls a clone of the queryset declared in the Metaclass.
        It is called every time a query is executed.
        Here the actual username and password is passed to the model.
        """         
        return Site.remote_supported.get_all(self.username,self.password)

问题是queryset声明在元类中只发生一次,而不是每次查询,因此从http请求获取的用户名和密码无法传递到元级别的查询。但是由于
get\u object\u list()
克隆了声明并使用updates参数值执行实际调用,这就完成了任务。它对我很有用,但我觉得应该有更好的解决方案。

为什么我必须使用
all()
?根据,它不是必要性。它不是必要性,但tastypie从
queryset
属性推断出一些数据,包括模型类。如果将
get\u all
方法添加到查询集,则可以始终过滤任何查询集,而无需ModelManager。由相应的ModelManager方法备份的自定义queryset方法确实使生活更轻松
class TestResource(ModelResource):

    class Meta:
        queryset = Test.remote_supported.get_all('dummyusername','dummypassword')
        resource_name = 'test'
        filtering = {
            'id' : ALL,
        }
        detail_allowed_methods = ['get', 'post', 'patch']       
        authorization = Authorization()
        authentication = MyCustomAuth()
        always_return_data = True

    def get_object_list(self, request):
        """
        This method calls a clone of the queryset declared in the Metaclass.
        It is called every time a query is executed.
        Here the actual username and password is passed to the model.
        """         
        return Site.remote_supported.get_all(self.username,self.password)