Ich möchte das Löschen einer Ressource mit einer benutzerdefinierten URL implementieren. Also, anstatt die DELETE auf der Standard-Ressource Tastypie URL zuzulassen, habe ich eine neue definiert. Das Löschen funktioniert, aber ich bekomme immer noch einen Fehler, weil ich sicher bin, dass etwas in meinem Code fehlt. Die Funktion zum Löschen ist cancel_ride_request
.Tastypie: Implementierung resoce DELETE auf benutzerdefinierte URL
class DemandResource(ModelResource):
"""
Handles ride requests resources. In particular:
- Offers information about the logged user's ride requests
- Allows new ride requests creation
"""
user = fields.ForeignKey(UserResource, 'passenger')
origin = fields.ForeignKey(NodeResource, 'origin', full=True)
destination = fields.ForeignKey(NodeResource, 'destination', full=True)
potential_drivers = fields.ListField(readonly=True)
class Meta:
queryset = api.models.Demand.objects.all()
resource_name = _Helpers.demand_resource_name
list_allowed_methods = ['get']
detail_allowed_methods = ['get', 'put', 'patch']
authentication = BasicAuthentication()
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/register%s" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('register_ride_request'), name="api_ask_ride"),
url(r"^(?P<resource_name>%s)/(?P<pk>.*?)/cancel%s" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('cancel_ride_request'), name="api_cancel_ride_request"),
]
@classmethod
def dehydrate_potential_drivers(cls, bundle):
return _Helpers.serialise_passengerships_passenger(bundle.obj.passengership_set.select_related().all())
def hydrate(self, bundle):
bundle.data['user'] = bundle.request.user
#extract orign and destination ID
bundle.data['origin'] = api.models.Node.objects.get(id=bundle.data['origin']['id'])
bundle.data['destination'] = api.models.Node.objects.get(id=bundle.data['destination']['id'])
bundle.data['arrival_time'] = datetime.strptime(bundle.data['arrival_time'], _Helpers.date_time_format)
tz = pytz.timezone('Europe/Brussels') #TODO get the user time zone
bundle.data['arrival_time'] = tz.localize(bundle.data['arrival_time'])
bundle.data['arrival_time_tolerance_early'] = timedelta(minutes=int(bundle.data['arrival_time_tolerance_early']))
bundle.data['arrival_time_tolerance_late'] = timedelta(minutes=int(bundle.data['arrival_time_tolerance_late']))
return bundle
def register_ride_request(self, request, **kwargs):
self.method_check(request, ['post', ])
self.is_authenticated(request)
data = json.loads(request.body)
bundle = self.build_bundle(data=data, request=request)
bundle = self.hydrate(bundle)
demand = api.models.Demand(passenger=bundle.request.user,
origin=bundle.data['origin'],
destination=bundle.data['destination'],
arrival_time=bundle.data['arrival_time'],
arrival_time_tolerance_early=bundle.data['arrival_time_tolerance_early'],
arrival_time_tolerance_late=bundle.data['arrival_time_tolerance_late'])
demand.save()
return HttpResponse(status=201)
"""
Handling demand deletion, making sure the request type is a DELETE and the user is authenticated
"""
def cancel_ride_request(self, request, **kwargs):
self.method_check(request, ['delete', ])
self.is_authenticated(request)
return api.models.Demand.objects.filter(pk=kwargs['pk']).delete()
"""
Makes sure that only the owner of a demand is able to delete it
"""
def delete_detail(self, object_list, bundle):
return bundle.obj.passenger == bundle.request.user
Ich denke, auch die Art, wie ich die Ressourcenerstellung mit der Funktion implementiert haben register_ride_request
nicht optimal ist. Es funktioniert, aber es ist seltsam, dass ich den Code HTTPResponse
manuell zurückgeben muss. Gibt es keinen besseren Weg, es zu tun? Danke und Entschuldigung für die zwei Fragen in einem Beitrag, aber ich fühle sie sind verwandt.