2013-06-14 9 views
5

Mam problemy z dodawaniem zasobów, powiązane przez użytkownika ApiKey, problemem jest właśnie pole "taxi", kiedy to skomentuję, "create_object" działa dobrze. JestOdwrotna relacja "ToManyField" w tastypie i obj_create error

Resouces

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) 

Modele

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) 

a błąd zasobu, o ile staram się tworzyć pewne zasoby to:

{"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"} 

Nie mam pojęcia o tym, co się dzieje, ale odwrotny stosunek "taksówka" jest dużym problemem.

Odpowiedz

2

Krótka odpowiedź:

Ponieważ pole taksówka nie jest prawdziwym polu w miejscu, chciałbym dodać „readonly = false” parametr do swojej dziedzinie taksówek w definicji LocationResource.

Ponadto, można po prostu usunąć pole taksówek i dodać go w metodzie dehydratowanej

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 

Długi asnswer:

Problemem jest to, że mówisz tastypie że LocationResource ma pole ToManyField nazwie Taxi. Ponieważ jest to ModelResource, tastypie przetłumaczy, że twój model lokalizacji ma pole taksówkowe typu ManyToManyField.

w Django, po utworzeniu nowej relacji w stosunku ManyToMany, że odbywa się to w sposób następujący:

location.taxis.add(taxi) 

Teraz w konfiguracji zasobów umieściłeś follwing:

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

ten stwierdza, że ​​gdy użytkownik spróbuje utworzyć nowy obiekt lokalizacji i wypełni pole taksówkowe, spróbuje wykonać następujące czynności:

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

Oczywiście obiekt Queryset nie ma metody "dodaj", ponieważ jest to po prostu zapytanie, a nie relacja ManyToMany.

Powiązane problemy