© 2020, Developed by Hieu Dev

Tổng hợp 10 tips hữu ích khi làm việc với Django REST framework hiệu quả

Django là một framework tuyệt vời để phát triển web với python, hiện tại nó đang phổ biến và được tiếp cận. Cụ thể các ông lớn đã áp dụng công nghệ này chẳng hạn như Instagram, Pinterest, Youtube, Spotify, Bitbucket,...

Tổng hợp 10 tips hữu ích khi làm việc với Django REST framework hiệu quả

1. Sử dụng request.user trong Middleware

Middleware cho phép bạn xử lý các requests từ browser trước khi chúng đến view của Django, cũng như requests từ view trước khi chúng đến browser.

Khác với các ngôn ngữ khác, trong thiết kế của Django Rest Framework không sẵn có request.user trong Middleware.

Và dưới đây là giải pháp:

from rest_framework.authentication import TokenAuthentication
from django.utils.functional import SimpleLazyObject
from django.utils.deprecation import MiddlewareMixin
from django.contrib.auth.middleware import get_user

class RestAuthMiddleware(MiddlewareMixin):

    def __init__(self, get_response):
        self.get_response = get_response

    @staticmethod
    def get_user(request):
        user = get_user(request)
        if user.is_authenticated:
            return user
        token_authentication = TokenAuthentication()
        try:
            user, token = token_authentication.authenticate(request)
        except:
            pass
        return user

    def __call__(self, request):
        request.user = SimpleLazyObject(lambda: self.__class__.get_user(request))
        response = self.get_response(request)
        return response


2. Pagination settings

Để các views sử dụng pagination, tất cả những gì chúng ta phải làm là ghi đè DEFAULT PAGINATION CLASS và PAGE_SIZE ở DRF settings trong settings.py như sau:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 20
}


3. Áp dụng querySet cho tất cả các rows, hoặc với fields cụ thể

Employees.objects.values_list('name', flat=True)

Như code trên, nhờ vào việc áp dụng querySet, ta đã lấy danh sách Employees chỉ với trường name. Như vậy, để lấy nhiều hơn, bạn chỉ cần thêm giá trị trong tuples:
 
Employees.objects.values_list('name', 'gender')


4. Aggregation with Filter

Trong Django, nếu chúng ta muốn có được một cái gì đó giống như tổng số người dùng và tổng số người dùng hoạt động, chúng tôi phải dùng đến các biểu thức có điều kiện, nó sẽ đơn giản như sau:
from django.contrib.auth.models import User
from django.db.models import Count, F
User.objects.aggregate(
    total_users=Count('id'),
    total_active_users=Count('id', filter=F('is_active')),
)

5. FK Indexes

Khi tạo một mô hình, Django sẽ tự động tạo một index B-Tree trên bất kỳ khoá ngoại (FK) nào. Indexes B-Tree có thể khá nặng và đôi khi chúng không thực sự cần thiết.

Trong Django, unique_together cũng sẽ tạo một index trên cả hai trường. Vì vậy, chúng tôi nhận được một model với hai field và ba index. Tùy thuộc vào công việc với mỗi model, có thể loại bỏ các chỉ mục FK và giữ chỉ một trong những được tạo ra bởi các ràng buộc duy nhất:

class MyModel(models.Model):
  field1 = models.CharField(max_length=50)
  field2 = models.CharField(max_length=50)

  class Meta:
    unique_together = (
             ('field1', 'field2',)
        )
    index_together = (
        ('field1', 'field2',)
)

6. Custom Validate Field

Trong Django, việc validate một trường có thể được viết trong model nhưng đối với một trường custom thì ta phải validate ở đây.

Dưới đây, ta có ví dụ kiểm tra trong tiêu đề có từ django hay không. không có sẽ báo lỗi.

class PostListSerializer(serializers.ModelSerializer):
    def validate_title(self, value):
        if 'django' not in value.lower():
        	raise serializers.ValidationError("Blog post is not about Django")
        return value


7. Serialier lồng nhau

Dưới đây, ta có ví dụ các Comment sẽ được tạo bởi User, vậy để lồng Serialier thì đơn giản sẽ như sau:

class UserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    username = serializers.CharField(max_length=100)

class CommentSerializer(serializers.Serializer):
    user = UserSerializer()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()


8. Customize field

Trong thực tế ta sẽ dùng một số custom field. Trong trường hợp này ta sẽ sử dùng property của Model hoặc nếu chỉ dùng trường đó cho riêng API thì ta dùng serializers.SerializerMethodField. giả sử trong trường hợp này ta format lại trường created.

class PostListSerializer(serializers.ModelSerializer):
    created_formated = serializers.SerializerMethodField(read_only=True)
       
    def get_created_formated(post)
    	return post.created.strftime("%d-%m-%Y") 
       
    class Meta:
        model = Post
        fields = ('title', 'content', 'draft', 'read_time', 'created_formated')
        read_only_fields = ('draft', 'read_time')
        


9. Exclude field

Trong trường hợp có quá nhiều trường mà ta chỉ bỏ 1 hoặc 2 trường. Thì việc liệt kê tất cả các trường ra là một cực hình. ta có thể dùng exclude thay cho fields, để chỉ ra những trường nào ko dùng trong model:

class PostListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        exclude = ('updated', 'created',)
        

Như ví dụ trên, chúng ta không dùng đến trường updated và created, ta đơn giản chỉ cần sử dụng exclude.

10. Limit

Trong Django, để giới hạn một truy vấn nhất định không quá 100 hàng, ta làm như sau:

data = Sale.objects.all()[:100]

Lời kết

Trong đây là những tips cơ bản hay gặp trong quá trình bạn làm việc với DRF, những hàm hữu dụng sẽ có trong các bài tiếp theo. Mong bài viết hữu ích với các bạn.


Hieu Ho.

1 Nhận xét

Mới hơn Cũ hơn