Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.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
Django Tastypie-在PUT上创建了错误的捆绑对象_Django_Tastypie - Fatal编程技术网

Django Tastypie-在PUT上创建了错误的捆绑对象

Django Tastypie-在PUT上创建了错误的捆绑对象,django,tastypie,Django,Tastypie,我发现了Tastypie创建捆绑包对象的一些问题: 1) 当我在不包含“id”字段的情况下对卡资源的详细端点执行PUT操作(请参见下面的tests.py),而不是从URI更新资源时,会创建一个新资源 2) 另一个更重要的问题是,如果我包括“id”字段,那么“id”中指示的资源将被更新,而不是URI中的资源;这意味着我可以通过指向任何其他详细URI来更新任何资源(我还没有在auth中构建,但这可能是将来的授权问题) 下面的第一个测试失败(除非我在模型字段定义中删除default=uuid1_as_

我发现了Tastypie创建捆绑包对象的一些问题:

1) 当我在不包含“id”字段的情况下对卡资源的详细端点执行PUT操作(请参见下面的tests.py),而不是从URI更新资源时,会创建一个新资源

2) 另一个更重要的问题是,如果我包括“id”字段,那么“id”中指示的资源将被更新,而不是URI中的资源;这意味着我可以通过指向任何其他详细URI来更新任何资源(我还没有在auth中构建,但这可能是将来的授权问题)

下面的第一个测试失败(除非我在模型字段定义中删除default=uuid1_as_base64并在模型的save方法中实现逻辑),下面的第二个测试通过,即使它不应该通过

这里发生了什么

tests.py 捆绑在上述测试期间创建的对象: models.py
def test_PUT_detail(self):

    # Test 1: PUT to detail endpoint of card 1 without an ID field

    put_data = {'text': 'wakka wakka'}
    response = self.api_client.put(
        uri='/api/v1/cards/rpHBJNOkEeKr2hTa6Uod1w/', # card 1 uri
        data=put_data
    )
    self.assertEqual(self.card_1.read_file(), 'wakka wakka')


    # Test 2: PUT to detail endpoint of card 1 with ID field of card 2

    put_data = {'id': 'twt_UtOkEeKsuxTa6Uod1w', 'text': 'wakka wakka'}
    response = self.api_client.put(
        uri='/api/v1/cards/rpHBJNOkEeKr2hTa6Uod1w/', # still card 1 uri
        data=put_data
    )
    self.assertEqual(self.card_2.read_file(), 'wakka wakka')
#Test 1
<Bundle for obj: 'rpHBJNOkEeKr2hTa6Uod1w' and with data: '{'text': u'wakka wakka', 'pk': u'rpHBJNOkEeKr2hTa6Uod1w'}'>

#Test 2 (notice how both the id field and pk field are included)
<Bundle for obj: 'twt_UtOkEeKsuxTa6Uod1w' and with data: '{'text': u'wakka wakka', 'id':   u'twt_UtOkEeKsuxTa6Uod1w', 'pk': u'rpHBJNOkEeKr2hTa6Uod1w'}'>
class CardResource(ModelResource):
    text = fields.CharField()

    def __init__(self, *args, **kwargs):
        super(CardResource, self).__init__(*args, **kwargs)
        self.fields['id'].read_only = True

    class Meta:
        queryset = Card.objects.all()
        fields = ['id', 'text']
        resource_name = 'cards'
        list_allowed_methods = ['get', 'post']
        detail_allowed_methods = ['get', 'put', 'delete']
        authorization = Authorization()
        validation = CardValidation()
        include_resource_uri = False

    def dehydrate_text(self, bundle):
        return bundle.obj.read_file()

    def save(self, *args, **kwargs):
        bundle = super(CardResource, self).save(*args, **kwargs)
        bundle.obj.write_file(bundle.data['text'])
        return bundle
class Card(TimeStampedModel):
    id = models.CharField(max_length=22, db_index=True, primary_key=True,
                          default=uuid1_as_base64) # default is a callable

    def file_path(self):
        return '/'.join([settings.CARD_ROOT, self.id + '.txt'])

    def read_file(self):
        try:
            with open(self.file_path(), 'rb') as f:
                content = f.read()
            return content
        except IOError:
            self.write_file(text='')
            return self.read_file()

    def write_file(self, text=''):
        with open(self.file_path(), 'wb') as f:
            f.write(text)

    def __unicode__(self):
        return u'%s' % self.id