Django REST framework: serializer không mô hình


158

Tôi là người mới bắt đầu trong khuôn khổ Django REST và cần lời khuyên của bạn. Tôi đang phát triển một dịch vụ web. Dịch vụ này phải cung cấp giao diện REST cho các dịch vụ khác. Giao diện REST, mà tôi cần triển khai, không hoạt động trực tiếp với các mô hình của tôi (ý tôi là các thao tác get, put, post, xóa). Thay vào đó, nó cung cấp các dịch vụ khác với một số kết quả tính toán. Theo yêu cầu, dịch vụ của tôi thực hiện một số tính toán và chỉ trả lại kết quả (không lưu trữ kết quả trong cơ sở dữ liệu của chính nó).

Dưới đây là sự hiểu biết của tôi về cách giao diện REST có thể được thực hiện. Đúng nếu tôi đã sai lầm.

  1. Tạo lớp mà làm cho các tính toán. Đặt tên là 'CalcClass'. CalcClass sử dụng các mô hình trong công việc của mình.
    • Params cần thiết cho các tính toán được chuyển đến các nhà xây dựng.
    • Thực hiện các hoạt động calc. Nó trả về kết quả là 'resultClass'.
  2. Tạo kết quả.
    • Xuất phát từ đối tượng.
    • Nó chỉ có các thuộc tính chứa kết quả calc.
    • Một phần của kết quả calc được biểu diễn dưới dạng bộ dữ liệu. Theo tôi hiểu, sẽ tốt hơn nếu tuần tự hóa tiếp theo để triển khai một lớp riêng cho các kết quả đó và thêm danh sách các đối tượng như vậy vào resultClass.
  3. Tạo serializer cho resultClass.
    • Xuất phát từ serializer.Serializer.
    • Các kết quả calc là chỉ đọc, do đó, sử dụng hầu hết lớp Trường cho các trường, thay vì các lớp chuyên biệt, chẳng hạn như IntegerField.
    • Tôi không nên thực hiện phương thức save () trên resultClass, cũng như trên serializer, vì tôi sẽ không lưu trữ kết quả (tôi chỉ muốn trả về chúng theo yêu cầu).
    • Impl serializer cho các kết quả lồng nhau (hãy nhớ bộ dữ liệu được đề cập ở trên).
  4. Tạo View để trả về kết quả tính toán.
    • Xuất phát từ APIView.
    • Chỉ cần có được ().
    • Trong get () tạo CalcClass với các tham số được lấy từ yêu cầu, gọi calc () của nó, lấy resultClass, tạo serializer và truyền resultClass cho nó, trả về hồi đáp (serializer.data).
  5. URL
    • Không có gốc api trong trường hợp của tôi. Tôi chỉ nên có URL để nhận kết quả calc khác nhau (calc với diff params).
    • Thêm định dạng cuộc gọi format_suffix_potypes để duyệt api.

Tôi đã bỏ lỡ một cái gì đó? Là cách tiếp cận là chính xác nói chung?


Cách tiếp cận này là chính xác và với tôi thực sự trông thanh lịch hơn câu trả lời được chấp nhận (dữ liệu kết quả được gói gọn trong một loại kết quả có thể sử dụng lại). Nhưng vào cuối ngày, điều này chủ yếu là một câu hỏi về sở thích cá nhân và cả hai phương pháp đều thực hiện công việc.
zepp.lee

Câu trả lời:


157

Django-rest-framework hoạt động tốt ngay cả khi không buộc nó vào mô hình. Cách tiếp cận của bạn nghe có vẻ ổn, nhưng tôi tin rằng bạn có thể cắt bớt một số bước để mọi thứ hoạt động.

Ví dụ, khung nghỉ ngơi đi kèm với một vài trình kết xuất được tích hợp sẵn. Khi ra khỏi hộp, nó có thể trả về JSON và XML cho người tiêu dùng API. Bạn cũng có thể kích hoạt YAML chỉ bằng cách cài đặt mô-đun python cần thiết. Django-rest-framework sẽ xuất ra bất kỳ đối tượng cơ bản nào như dict, list và tuple mà không cần thêm bất kỳ công việc nào từ phía bạn.

Vì vậy, về cơ bản, bạn chỉ phải tạo hàm hoặc lớp nhận các đối số, thực hiện tất cả các phép tính cần thiết và trả về kết quả của nó trong một tuple cho khung nhìn api REST. Nếu JSON và / hoặc XML phù hợp với nhu cầu của bạn, django-rest-framework sẽ đảm nhiệm việc tuần tự hóa cho bạn.

Bạn có thể bỏ qua bước 2 và 3 trong trường hợp này và chỉ sử dụng một lớp để tính toán và một lớp để trình bày cho người tiêu dùng API.

Dưới đây là một vài đoạn có thể giúp bạn hiểu:

Xin lưu ý rằng tôi đã không kiểm tra điều này. Nó chỉ có ý nghĩa như một ví dụ, nhưng nó sẽ hoạt động :)

Chiếc kính:

class CalcClass(object):

    def __init__(self, *args, **kw):
        # Initialize any variables you need from the input you get
        pass

    def do_work(self):
        # Do some calculations here
        # returns a tuple ((1,2,3, ), (4,5,6,))
        result = ((1,2,3, ), (4,5,6,)) # final result
        return result

Khung nhìn REST:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from MyProject.MyApp import CalcClass


class MyRESTView(APIView):

    def get(self, request, *args, **kw):
        # Process any get params that you may need
        # If you don't need to process get params,
        # you can skip this part
        get_arg1 = request.GET.get('arg1', None)
        get_arg2 = request.GET.get('arg2', None)

        # Any URL parameters get passed in **kw
        myClass = CalcClass(get_arg1, get_arg2, *args, **kw)
        result = myClass.do_work()
        response = Response(result, status=status.HTTP_200_OK)
        return response

Urls.py của bạn:

from MyProject.MyApp.views import MyRESTView
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    # this URL passes resource_id in **kw to MyRESTView
    url(r'^api/v1.0/resource/(?P<resource_id>\d+)[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
    url(r'^api/v1.0/resource[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'),
)

Mã này sẽ xuất ra một danh sách các danh sách khi bạn truy cập http://example.com/api/v1.0/resource/?format=json . Nếu sử dụng hậu tố, bạn có thể thay thế ?format=jsonbằng .json. Bạn cũng có thể chỉ định mã hóa bạn muốn lấy lại bằng cách thêm "Content-type"hoặc "Accept"vào các tiêu đề.

[
  [
    1, 
    2, 
    3
  ], 
  [
    4, 
    5, 
    6
  ]
]

Hy vọng điều này sẽ giúp bạn ra ngoài.


2
Chào Gabriel! Cảm ơn bạn vì câu trả lời! Tôi đã thực hiện những gì tôi cần theo kế hoạch của tôi. Hoạt động tốt! Tôi đã sử dụng serializer cho đầu ra json tốt hơn.
Zakhar

3
Tôi đã cố gắng làm theo đề xuất này nhưng tôi nhận được: "Không thể áp dụng DjangoModelPermissions trên một quan điểm không có .modelhoặc .querysettài sản.". Tôi đã thử ví dụ chính xác được cung cấp. Nó có thể là một cái gì đó với phiên bản gần đây của django-rest-framework?
Orlando

Ví dụ này đã được viết cách đây một thời gian. Tôi đã không có cơ hội làm việc với Django nữa. nhưng bạn có thể tìm thấy thứ gì đó hữu ích ở đây: django-rest-framework.org/api-guide/routers
Gabriel Samfira

1
Ví dụ này chính xác là những gì tôi cần cho nhu cầu của tôi là một dịch vụ đang thực hiện một số hoạt động mà không có bộ nối tiếp không mô hình!
Khalil TABBAL

@Orlando: Xem ở đây cách triển khai logic cấp phép cụ thể cho chế độ xem không phải mô hình với djang-restframework 3: stackoverflow.com/a/34040070/640916
djangonaut

-1

Trong url url, hàm login_Vquired yêu cầu

from django.contrib.auth.decorators import login_required

nếu đó chỉ là một nhận xét thay vì một câu trả lời, hãy cân nhắc sử dụng add a commentphiên
lucascavalcante
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.