2010-12-27 30 views
11

Tôi đang cố gắng sử dụng Piston để cung cấp hỗ trợ REST cho Django. Tôi đã triển khai trình xử lý của mình theo tài liệu được cung cấp. Vấn đề là tôi có thể "đọc" và "xóa" tài nguyên của tôi nhưng tôi không thể "tạo" hoặc "cập nhật". Mỗi lần tôi nhấn api liên quan tôi nhận được một lỗi yêu cầu 400 Bad.Tôi nhận được lỗi Yêu cầu Lỗi 400 trong khi sử dụng django-piston

tôi đã mở rộng các lớp tài nguyên cho CSRF bằng cách sử dụng đoạn mã thường có sẵn này:

class CsrfExemptResource(Resource): 
    """A Custom Resource that is csrf exempt""" 
    def __init__(self, handler, authentication=None): 
     super(CsrfExemptResource, self).__init__(handler, authentication) 
     self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True) 

My lớp (đoạn mã) trông như thế này:

user_resource = CsrfExemptResource(User) 

class User(BaseHandler): 
    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') 

    @require_extended 
    def create(self, request): 
     email = request.GET['email'] 
     password = request.GET['password'] 
     phoneNumber = request.GET['phoneNumber'] 
     firstName = request.GET['firstName'] 
     lastName = request.GET['lastName'] 
     self.createNewUser(self, email,password,phoneNumber,firstName,lastName) 
     return rc.CREATED 

Xin vui lòng cho tôi biết làm thế nào có thể tôi có được phương pháp tạo để làm việc bằng cách sử dụng các hoạt động POST?

+0

Ok, tôi đã nhận xét "django.middleware.csrf.CsrfViewMiddleware" từ tệp cài đặt thay vì sử dụng phần mở rộng của Lớp tài nguyên. Tôi vẫn thấy vấn đề này mặc dù – Cheezo

+0

Bạn đang cố gắng thực hiện thao tác HTTP "PUT" hoặc "POST" tương ứng với "tạo" hoặc "cập nhật" như thế nào? Làm cách nào để bạn biết mã phía máy khách này đang tạo yêu cầu HTTP đúng và hợp lệ? –

+0

Đối với POST, tôi sử dụng WizTools.org để từ đó tôi có thể tạo một yêu cầu POST một cách rõ ràng. Ít nhất tôi chắc chắn về yêu cầu đó và điều đó là đủ tôi đoán. – Cheezo

Trả lời

1

Trong utils.py, hãy thay đổi điều này.

def content_type(self): 
    """ 
    Returns the content type of the request in all cases where it is 
    different than a submitted form - application/x-www-form-urlencoded 
    """ 
    type_formencoded = "application/x-www-form-urlencoded" 

    ctype = self.request.META.get('CONTENT_TYPE', type_formencoded) 

    if ctype.strip().lower().find(type_formencoded) >= 0: 
     return None 

    return ctype 

https://bitbucket.org/jespern/django-piston/issue/87/split-charset-encoding-form-content-type

10

này đang xảy ra vì Piston không thích thực tế là ExtJS được đặt "charset = UTF-8" trong content-type của tiêu đề.

Dễ dàng cố định bằng cách thêm một số trung gian để làm cho nội dung-type hơn một chút Piston thân thiện, tạo ra một tập tin gọi là middleware.py trong thư mục cơ sở ứng dụng của bạn:

class ContentTypeMiddleware(object): 

    def process_request(self, request): 
     if request.META['CONTENT_TYPE'] == 'application/x-www-form-urlencoded; charset=UTF-8': 
      request.META['CONTENT_TYPE'] = 'application/x-www-form-urlencoded' 
     return None 

Sau đó chỉ cần bao gồm middleware này trong cài đặt của bạn py:

MIDDLEWARE_CLASSES = (
    'appname.middleware.ContentTypeMiddleware', 
) 
7

giải pháp được đề xuất vẫn không làm việc cho tôi (django 1.2.3/piston 0.2.2) vì vậy tôi đã điều chỉnh joekrell giải pháp và điều này cuối cùng làm việc (tôi chỉ sử dụng POST và PUT, nhưng có lẽ bạn có thể thêm các động từ khác vào danh sách):

class ContentTypeMiddleware(object): 

def process_request(self, request): 

    if request.method in ('POST', 'PUT'): 
     # dont break the multi-part headers ! 
     if not 'boundary=' in request.META['CONTENT_TYPE']: 
      del request.META['CONTENT_TYPE'] 

với:

MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware', 
) 

tôi đã không nhận thấy bất kỳ tác dụng phụ, nhưng tôi không thể hứa đó là chống đạn.

+2

Có, giải pháp của bạn đã làm việc cho tôi (Django 1.3, Piston 0.2.2). Nói chung có vẻ như Piston đã trở thành một sản phẩm từ bỏ --- nó không được cập nhật trong một thời gian dài. –

4

tôi đã kết hợp một số những gì người khác đã nói, và thêm hỗ trợ cho bất kỳ loại nội dung, json ví dụ ...

class ContentTypeMiddleware(object): 
    def process_request(self, request): 
     if request.method in ('POST', 'PUT') and request.META['CONTENT_TYPE'].count(";") > 0: 
      request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0] 
     return None 
+0

Đây là giải pháp tốt nhất. Cảm ơn bạn. – GivP

+0

bằng cách sử dụng này cho POST đã phá vỡ các công cụ khác nhưng nó cố định vấn đề của tôi khi sử dụng chỉ cho PUT –

4

Tôi nghĩ giải pháp của Eric làm việc tốt nhất nhưng sau đó chạy vào vấn đề khi lưu những thứ trong admin. tinh chỉnh này dường như để sửa chữa nó nếu bất cứ ai khác đi qua nó:

class ContentTypeMiddleware(object): 

    def process_request(self, request): 
     if request.method in ('POST') and not 'boundary=' in request.META['CONTENT_TYPE']: 
      request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0] 
     return None 
1

Đây là giải pháp mà làm việc cho tôi, sau một tinh chỉnh:

class ContentTypeMiddleware(object): 

    def process_request(self, request): 
     if 'charset=UTF-8' in request.META['CONTENT_TYPE']: 
      request.META['CONTENT_TYPE'] = request.META['CONTENT_TYPE'].replace('; charset=UTF-8','') 
     return None 
0

Chúng tôi đã có một nguồn tài nguyên đã được chỉ đơn giản là cập nhật một dấu thời gian dựa về thông tin đăng nhập yêu cầu và PUT. Nó chỉ ra rằng Piston không giống như PUT mà không có một tải trọng. Việc thêm một tải trọng chuỗi rỗng '' đã sửa nó.

Tìm kiếm nhanh trên Google cho biết rằng các hệ thống khác như Apache có thể không thích PUT mà không cần tải trọng.

Các vấn đề liên quan