Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.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以将字段视为唯一字段?_Python_Django_Tastypie - Fatal编程技术网

Python 如何配置Tastypie以将字段视为唯一字段?

Python 如何配置Tastypie以将字段视为唯一字段?,python,django,tastypie,Python,Django,Tastypie,如何配置Tastypie以将字段视为唯一字段?如果我尝试为标记为唯一的字段插入重复条目,我的期望是收到某种非500错误(可能是409冲突?)作为响应 我已经看过了这些文件,看起来我应该很清楚,但由于某些原因,我没有得到我期望看到的回应 以下是文档链接: 示例代码如下所示: url.py v1_api = Api(api_name='v1') v1_api.register(CompanyResource()) urlpatterns = patterns('', (r'^api/

如何配置Tastypie以将字段视为唯一字段?如果我尝试为标记为唯一的字段插入重复条目,我的期望是收到某种非500错误(可能是409冲突?)作为响应


我已经看过了这些文件,看起来我应该很清楚,但由于某些原因,我没有得到我期望看到的回应

以下是文档链接:


示例代码如下所示:

url.py

v1_api = Api(api_name='v1')
v1_api.register(CompanyResource())

urlpatterns = patterns('',
    (r'^api/', include(v1_api.urls)),
)
resource.py

class CompanyResource(ModelResource):

    CompanyName = fields.CharField(attribute='company_name')
    CompanyId = fields.CharField(attribute='company_id', unique=True)
    Contact = fields.CharField(attribute='contact')
    Email = fields.CharField(attribute='email')
    Phone = fields.CharField(attribute='phone')

    class Meta:
        queryset = Company.objects.all()
        authentication = BasicAuthentication()
        authorization = Authorization()
        allowed_methods = ['get', 'post']
models.py

class Company(models.Model):

    company_name = models.TextField(default=None, blank=True, null=True)
    company_id = models.CharField(default='', unique=True, db_index=True, max_length=20)
    contact = models.TextField(default=None, blank=True, null=True)
    email = models.EmailField(default=None, blank=True, null=True)
    phone = models.TextField(default=None, blank=True, null=True)

我收到的错误如下(使用curl访问我的本地服务):

curl--dump header--H“内容类型:application/json”-X POST--user-user:password--data'{“CompanyName”:“company”,“CompanyId”:“1234567890”,“Contact”:“John”,“Email”:example@example.com“,”电话“:“555-555-5555”}”http://localhost:8000/api/v1/company/
HTTP/1.0 500内部服务器错误
日期:2011年9月15日星期四18:25:20 GMT
服务器:WSGIServer/0.1 Python/2.7.1
内容类型:application/json;字符集=utf-8
{“错误消息”:(1062,\“重复条目'1234567890'用于键'api\公司\公司id\ uniq'\”),
......
raise ERRORCASE,errorvalue\n\n集成错误:(1062,\“重复条目'1234567890'用于键'api\U company\U company\U id\U uniq'\”)\n“}

当我从公司模型中删除
unique=True,db_index=True,
时,我没有收到完整性错误,而是创建了一个新的重复资源。同样,这不是预期的结果,因为我希望unique执行一些验证并引起一些非500响应。

以下是我解决问题的方法:

基于用于验证的文档,我能够实现一个自定义验证器,该验证器为我检查字段的唯一性。

在CompanyResource中,我向meta类添加了CustomValidation。我将CustomValidation的实现放在validations.py文件中。如果isValid返回错误,api将返回400,其中包含错误中包含的消息

class CompanyResource(ModelResource):
    """
    CompanyIds should be unique
    """     
    CompanyName = fields.CharField(attribute='company_name')     
    CompanyId = fields.CharField(attribute='company_id', unique=True)     
    Contact = fields.CharField(attribute='contact')     
    Email = fields.CharField(attribute='email')     
    Phone = fields.CharField(attribute='phone')    

    class Meta:        
        queryset = Company.objects.all()        
        authentication = BasicAuthentication()        
        authorization = Authorization()        
        allowed_methods = ['get', 'post']                
        validation = CustomValidation()
validations.py

class CustomValidation(Validation):
    """
    The custom validation checks two things:
       1) that there is data
       2) that the CompanyId exists (unique check)
    """
    def is_valid(self, bundle, request=None):
        if not bundle.data:
            return {'__all__': 'Missing data, please include CompanyName, CompanyId, Contact, Email, and Phone.'}

        errors = {}                                    
        company_id=bundle.data.get('CompanyId', None)

        # manager method, returns true if the company exists, false otherwise
        if Company.objects.company_exists(company_id):
            errors['CompanyId']='Duplicate CompanyId, CompanyId %s already exists.' % company_id
        return errors

我今天也遇到了同样的问题。以下是我如何处理的:

覆盖资源定义中的[request\u method]\uRequest\u type]方法。例如,我覆盖FooResource中的post\u列表:

def post_list(self, request, **kwargs):
    from django.db import IntegrityError
    try:
        return super(FooResource, self).post_list(request, **kwargs)
    except IntegrityError, e:
        if e.args[0] == 1062:
            return http.HttpConflict()

希望它对您有用。

出于价值考虑,我创建了一个稍有不同的解决方案,对我更有效。它基于thoslin的答案

我发现e.args[0]==1062检查对我来说失败了。我很确定这是一个MySQL错误,我正在使用Postgres

我还在obj_create方法中实现了这一点,这样它将处理所有对象的创建,而不仅仅是通过post_list完成的创建

from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpConflict
from django.db import IntegrityError

...

class MyBaseResource(ModelResource):
    def obj_create(self, bundle, **kwargs):
        try:
            return super(MyBaseResource, self).obj_create(bundle, **kwargs)
        except IntegrityError, e:
            if e.args[0] == 1062 or e.args[0].startswith('duplicate key'):
                raise ImmediateHttpResponse(HttpConflict())

...

class MyResource(MyBaseResource):
    [usual resource stuff]

对于定义为blank=True的模型字段,我也面临着同样的问题。Tastypie正在使用空白条目创建记录。我的答案是使用validation=FormValidation(form\u class=)。这会根据模型的字段进行验证。不会。如果需要PUT支持,则需要使用上面的“thoslins”方法。为什么选择在方法中导入IntegrityError?
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.http import HttpConflict
from django.db import IntegrityError

...

class MyBaseResource(ModelResource):
    def obj_create(self, bundle, **kwargs):
        try:
            return super(MyBaseResource, self).obj_create(bundle, **kwargs)
        except IntegrityError, e:
            if e.args[0] == 1062 or e.args[0].startswith('duplicate key'):
                raise ImmediateHttpResponse(HttpConflict())

...

class MyResource(MyBaseResource):
    [usual resource stuff]