如何编写django-piston处理程序来创建和返回ApiKey?

时间:2012-08-11 14:11:19

标签: django api rest django-piston

我目前正在开发使用Android for client和Django for web server的项目。我决定使用piston-django来创建REST API身份验证,我遵循以下指令: What is the right way to write a django-piston client? 并编写我自己的处理程序(api / handlers.py)来创建和返回ApiKey,如下所示:

class ApiKeyhandler(Basehandler):
    model = ApiKey
    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
    fields = ('user', 'keys')

    def create(self, request):
        attrs = self.flatten_dict(request.POST)

        if self.exists(**attrs):
            return rc.DUPLICATE_ENTRY
        else:
            apikey = ApiKey(user=request.user)
            apikey.save()

            return apikey

并在urls.py中为此处理程序使用HttpBasicAuthentication:

 auth = HttpBasicAuthentication(realm="Authentication API")
 apikey = Resource(handler=ApiKeyHandler, authentication=auth)

但是当我使用http://hurl.it

进行测试时

This is the response from GET

This is the response from POST method

有人能告诉我如何编写此问题的完整代码或有关此问题的任何建议吗?

1 个答案:

答案 0 :(得分:2)

由于没有人回答这个问题,我自己想出来并得到了朋友的帮助。我必须将ApiKeyHandler编辑为

class ApiKeyHandler(BaseHandler):
    model = ApiKey
    allowed_methods = ('GET', 'POST')
    fileds = ('user', 'key')

    def read(self, request):
        # Return the API key for request.user
        values_query_set = request.user.keys.values('key')
        api_key = list(values_query_set)[0]['key']
        return HttpResponse(api_key)

    def create(self, request):
        #Create a new API Key.

        # Check if API key already exists
        if request.user.keys.count() > 0:
            values_query_set = request.user.keys.values('key')
            api_key = list(values_query_set)[0]['key']
            return HttpResponse(api_key)
        else:
            # Create API key
            api_key = ApiKey(user=request.user)
            api_key.save()
        return HttpResponse(api_key)

根据django-piston doc方法,在GET上调用read,在POST上调用方法create。因此,当客户想要创建新的API密钥时;如果API密钥尚不存在,客户端需要请求HTTP POST为request.user创建API密钥。

最后在models.py中,我需要将ApiKey模型编辑为

class ApiKey(models.Model):
    user = models.ForeignKey(User, related_name='keys', unique=True)
    key = models.CharField(max_length=KEY_SIZE, null=True, blank=True)

    def save(self, *args, **kwargs):
        self.key = User.objects.make_random_password(length=KEY_SIZE)

        while ApiKey.objects.filter(key__exact=self.key).count():
            self.key = User.objects.make_random_password(length=KEY_SIZE)

        super(ApiKey, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.key

We need to call the "real" save() method

super(ApiKey, self).save(*args, **kwargs)

和APIKeyAuthenticatin现在正在运作。

最后但并非最不重要的是,在对用户进行身份验证时,客户端需要使用HEADER('Authorization',api_key)请求HTTP请求。api_key必须与request.user匹配。