5

ApiKey ユーザーに関連するリソースの追加で問題が発生しています。問題はまさに「タクシー」フィールドです。コメントすると、「create_object」は正常に機能します。資源はある

リソース

class LocationResource(ModelResource):
    user = fields.ForeignKey(AccountResource, 'user', full=True)
    taxi = fields.ToManyField(TaxiResource, attribute=lambda bundle: Taxi.objects.filter(user=bundle.obj.user), full=True, null=True)

    class Meta:
        queryset = Location.objects.all().order_by('-id')
        resource_name = 'location'
        list_allowed_methods = ['post', 'get']
        authentication = ApiKeyAuthentication()
        authorization = Authorization()
        filtering = {'user': ALL_WITH_RELATIONS}

    def obj_create(self, bundle, **kwargs):
        if bundle.request.method == 'POST':
            return super(LocationResource, self).obj_create(bundle, user=bundle.request.user)

モデル

from django.contrib.auth.models import User

class Taxi(models.Model):
    STATUS_CHOICES = (
        ('Av', 'Available'),
        ('NA', 'Not Available'),
        ('Aw', 'Away'),
    )
    user = models.OneToOneField(User)
    license_plate = models.TextField(u'Licence Plate',max_length=6,blank=True,null=True)
    status = models.CharField(u'Status',max_length=2,choices=STATUS_CHOICES)
    device = models.OneToOneField(Device, null=True)
    def __unicode__(self):
        return "Taxi %s for user %s" % (self.license_plate,self.user)


class Location(models.Model):
    user = models.ForeignKey(User)
    latitude = models.CharField(u'Latitude', max_length=25, blank=True, null=True)
    longitude = models.CharField(u'Longitude', max_length=25, blank=True, null=True)
    speed = models.CharField(u'Speed', max_length=25, blank=True, null=True)
    timestamp = models.DateTimeField(auto_now_add=True)
    def __unicode__(self):
        return "(%s,%s) for user %s" % (self.latitude, self.longitude,self.user)

そして、いくつかのリソースを作成しようとしたときのエラーは次のとおりです。

{"error_message": "'QuerySet' object has no attribute 'add'", "traceback": "Traceback (most recent call last):\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 217, in wrapper\n    response = callback(request, *args, **kwargs)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 459, in dispatch_list\n    return self.dispatch('list', request, **kwargs)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 491, in dispatch\n    response = method(request, **kwargs)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 1357, in post_list\n updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))\n\n  File \"/Users/phantomis/Memoria/smartaxi_server/geolocation/api.py\", line 111, in obj_create\n    return super(LocationResource, self).obj_create(bundle, user=bundle.request.user)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 2150, in obj_create\n    return self.save(bundle)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 2301, in save\n    self.save_m2m(m2m_bundle)\n\n  File \"/Users/phantomis/Virtualenvs/django-memoria/lib/python2.7/site-packages/tastypie/resources.py\", line 2432, in save_m2m\n    related_mngr.add(*related_objs)\n\nAttributeError: 'QuerySet' object has no attribute 'add'\n"}

何が起こっているのかさっぱりわかりませんが、逆の関係の「タクシー」が大問題です。

4

1 に答える 1

2

簡潔な答え:

タクシー フィールドは場所の実際のフィールドではないため、LocationResource 定義のタクシー フィールドに "readonly=false" パラメーターを追加します。

また、単純にタクシー フィールドを削除して、それを dehydrate メソッドに追加することもできます。

def dehydrate(self, bundle):
     """ LocationResource dehydrate method.

     Adds taxi urls
     """
     taxi_resource = TaxiResource()
     bundle.data['taxi'] = []

     for taxi in Taxi.objects.filter(user=bundle.obj.user):
         taxi_uri = taxi_resource.get_resource_uri(taxi)
         bundle.data['taxi'].append(taxi_uri)

     return bundle

長い答え:

問題は、LocationResource にタクシーと呼ばれる ToManyField フィールドがあることを Tastypie に伝えていることです。これは ModelResource であるため、tastypie は Location モデルに ManyToManyField タイプのタクシー フィールドがあると解釈します。

django では、ManyToMany 関係で新しい関係を作成する場合、次のように行われます。

location.taxis.add(taxi)

ここで、Resource 構成に次のものを配置しました。

taxi = fields.ToManyField(
    TaxiResource, 
    attribute=lambda bundle: Taxi.objects.filter(user=bundle.obj.user),
    full=True, null=True
)

これは、tastypie が新しい Location オブジェクトを作成しようとするときに、タクシー フィールドに入力すると、次のことを試みることを示しています。

Taxi.objects.filter(user=bundle.obj.unser).add(taxi)

明らかに、Queryset オブジェクトには「add」メソッドがありません。これは単なるクエリセットであり、ManyToMany の関係ではないためです。

于 2013-10-04T19:09:42.880 に答える