12/08/2018, 18:05

Xây dựng nhanh chóng API với Django Tastypie [Phần 3]

Tiếp theo phần 1 và phần 2, phần 3 này mình sẽ giới thiệu về cách sử dụng Non-ORM Data Sources trong Tastypie Requirement trước khi đọc phần này là bạn phải đọc qua phần 1 tại đây Okay, vì sao mình lại giới thiệu phần này? Khi bạn đã cảm thấy quá bí bách với Tastypie. Khi bạn cảm thấy quá nhàm ...

Tiếp theo phần 1 và phần 2, phần 3 này mình sẽ giới thiệu về cách sử dụng Non-ORM Data Sources trong Tastypie Requirement trước khi đọc phần này là bạn phải đọc qua phần 1 tại đây

Okay, vì sao mình lại giới thiệu phần này? Khi bạn đã cảm thấy quá bí bách với Tastypie. Khi bạn cảm thấy quá nhàm chán. Khi bạn không muốn response có những dữ liệu mà thông qua tính toán không lưu trong model, blabla...

Tastypie định hướng được xây dựng để xử lý Non-ORM data. Không dài dòng nữa, bắt đầu nào!

Tastypie cung cấp class Resource. Class này cung cấp rất nhiều thứ sẵn có cho bạn tương tự như ModelResource:

  • authentication
  • authorization
  • caching
  • serialization ...

Chúng ta sẽ có 9 method cần phải implement nếu cần full read-write một API:

  • detail_uri_kwargs
  • get_object_list
  • obj_get_list
  • obj_get
  • obj_create
  • obj_update
  • obj_delete_list
  • obj_delete
  • rollback

Tất nhiên, nếu bạn không cần full read-write, bạn có thể chỉ cần implement một số methods thôi.

Bài toán: Tạo endpoint ProfileUser đáp ứng các nhu cầu:

  • Hiển thị list profile
  • Hiển thị một profile
  • Create mới một profile
  • Update một profile
  • Delete một profile

Đầu tiên mình tạo 2 class:

class ProfileObject(object):
    def __init__(self, initial=None):
        self.__dict__['_data'] = {}

        if hasattr(initial, 'items'):
            self.__dict__['_data'] = initial

    def __getattr__(self, name):
        return self._data.get(name, None)

    def __setattr__(self, name, value):
        self.__dict__['_data'][name] = value

    def to_dict(self):
        return self._data


class ProfileResource(Resource):
    user_id = IntegerField(attribute='user_id')
    username = CharField(attribute='username')
    slug = CharField(attribute='slug')
    avatar = CharField(attribute='avatar')
    email = CharField(attribute='email')
    phone = CharField(attribute='phone')
    star = IntegerField(attribute='star')

    class Meta:
        resource_name = 'profile'
        object_class = ProfileObject

Trong ví dụ trên:

  • ProfileObject: class này để chúng ta đẩy dữ liệu vào và lấy dữ liệu ra
  • MessageResource: class này sẽ define các field tương ứng với data type của từng field

Ok. Mình sẽ đi vào từng feature:

List profile

def obj_get_list(self, bundle, **kwargs):
    return  self.get_object_list(bundle.request)

def get_object_list(self, request):
    fix_data = [
        {
            "user_id": 1,
            "username": "minhhahao",
            "slug": "/minhhahao",
            "avatar": "https://google.com",
            "email": "minhhahao@abc.com",
            "phone": "0123456789",
            "star": 9999
        },
        {
            "user_id": 2,
            "username": "ha.hao.minh",
            "slug": "/ha.hao.minh",
            "avatar": "https://google.com",
            "email": "ha.hao.minh@abc.com",
            "phone": "0987654321",
            "star": 8888
        },
        {
            "user_id": 3,
            "username": "nguyenthivan",
            "slug": "/nguyenthivan",
            "avatar": "https://google.com",
            "email": "nguyenthivan@abc.com",
            "phone": "0987654321123",
            "star": 7777
        }
    ]

    results = [ProfileObject(initial=data) for data in fix_data]

    return results

Ở đây mình sẽ override 2 methods mình đã liệt kê bên đầu bài đó là: get_object_list, obj_get_list. Biến fix_data là dữ liệu mình hard code ra. Sau đó mình chuyển dữ liệu đó vào ProfileObject. Cuối cùng trả về list ProfileObject. Ở đây, với từng bài toán cụ thể bạn có thể query các kiểu để có dữ liệu. Vì là demo nên mình sử dụng fix data. Ngoài ra, do mặc định Tastypie, get list object sẽ luôn trả về resource_uri. Nhưng mình không muốn hiển thị cái này ở response. Vậy nên mình sẽ disable nó đi             </div>
            
            <div class=

0