【问题标题】:Foreign key managment in Django TastypieDjango Tastypie 中的外键管理
【发布时间】:2016-02-02 06:00:32
【问题描述】:

我正在尝试使用 API 插入数据,并希望管理将数据传递给外键的方式。但是我不断得到空值,即使它们在包中不为空

模型.PY

class LCUser(models.Model):
        email = models.CharField(max_length=100,unique=True)
        password = models.CharField(max_length=100)
        first_name = models.CharField(max_length=100)
        last_name=models.CharField(max_length=100)

        class Meta:
            db_table = "user"

    class UserProfile(models.Model):
        user = models.ForeignKey(LCUser, on_delete=models.CASCADE,primary_key=True)
        mobile_phone = models.IntegerField()
        city=models.CharField(max_length=50)

        class Meta:
            db_table = "profile"

API.PY

class MultipartResource(object):

    def deserialize(self, request, data, format=None):

        if not format:
            format = request.META.get('CONTENT_TYPE', 'application/json')

        if format == 'application/x-www-form-urlencoded':
            return request.POST

        if format.startswith('multipart/form-data'):
            multipart_data = request.POST.copy()
            multipart_data.update(request.FILES)
            return multipart_data

        return super(MultipartResource, self).deserialize(request, data, format)

    def put_detail(self, request, **kwargs):
        if request.META.get('CONTENT_TYPE', '').startswith('multipart/form-data') and not hasattr(request, '_body'):
            request._body = ''
        return super(MultipartResource, self).put_detail(request, **kwargs)

    def patch_detail(self, request, **kwargs):
        if request.META.get('CONTENT_TYPE', '').startswith('multipart/form-data') and not hasattr(request, '_body'):
            request._body = ''
        return super(MultipartResource, self).patch_detail(request, **kwargs)    

class ProfileResource(MultipartResource,ModelResource):
#Get the id from the request and obtain the correcct user object
    user_id = LCUser.objects.get(id=1)  #For testing
    class Meta:
        queryset = UserProfile.objects.all()
        resource_name = 'profile'
        authorization = Authorization()

    def obj_create(self,bundle,request=None,**kwargs):
        try:
            print repr(bundle)
            bundle = super(ProfileResource, self).obj_create(bundle, request=request, **kwargs)
            bundle.obj.save()
        except:
            traceback.print_exc()
            raise BadRequest('Error')
        return bundle

请求

POST /api/profile/? HTTP/1.1
Host: 127.0.0.1:8000
Cache-Control: no-cache
Postman-Token: c3cddfd3-a2ec-06fc-e916-ed5ff8f21077
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="user"

1
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="mobile_phone"

123
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="city"

123

当我尝试插入时出现完整性错误, IntegrityError:“user_id”列中的空值违反非空约束 失败的行包含 (null, 123, 123)

捆绑

<Bundle for obj: 'UserProfile object' and with data: '{'mobile_phone': u'123', 'user': u'1', 'city': u'123'}'>

【问题讨论】:

    标签: django tastypie


    【解决方案1】:

    您需要在资源上手动指定相关字段:http://django-tastypie.readthedocs.org/en/latest/fields.html?highlight=meta#toonefield

    class UserResource(MultipartResource, ModelResource):
        class Meta:
            queryset = User.objects.all()
            resource_name = 'user'
    
    class ProfileResource(MultipartResource, ModelResource):
        user = fields.ToOneField(UserResource)
    
        class Meta:
            queryset = UserProfile.objects.all()
            resource_name = 'profile'
            authorization = Authorization()
    
        def obj_create(self, bundle, request=None, **kwargs):
            try:
                print repr(bundle)
                bundle = super(ProfileResource, self).obj_create(bundle, request=request, **kwargs)
                bundle.obj.save()
            except:
                traceback.print_exc()
                raise BadRequest('Error')
            return bundle
    

    另外,不要忘记配置您的授权和身份验证。

    【讨论】:

      【解决方案2】:

      我设法通过覆盖 obj_create 方法来修复它。

      def obj_create(self, bundle, request=None, **kwargs):
          try:
              bundle.obj = UserProfile(user_id=bundle.data['user'], mobile_phone=bundle.data['mobile_phone'],city=bundle.data['city'])
              bundle.obj.save()
          except:
              traceback.print_exc()
              raise #On error raise it back to wrap_view()
          return bundle
      

      【讨论】:

      • 但是您是“解决”了您的问题还是只是实施了“破解”?正如 Sean 指出的,修复引用的正确方法是在资源中定义该引用。
      猜你喜欢
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 2022-11-13
      相关资源
      最近更新 更多