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,...
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',)
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.
Nguồn tham khảo: https://medium.com/analytics-vidhya/10-must-have-tips-of-django-rest-framework-to-increase-your-coding-efficiency-87ebea0e0099
Hieu Ho.
bài viết hữu ích quá ạ
Trả lờiXóa