Mixin hợp khi có một behaviour lặp ở nhiều CBV không liên quan model — auth check, scope theo tenant, gắn extra context.
Mixin phải kế thừa từ object (không phải View), override một method ngắn, và gọi super() đúng cách.
python
class TenantScopedMixin:
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(tenant=self.request.tenant)
class AuditedDeleteMixin:
def form_valid(self, form):
response = super().form_valid(form)
AuditLog.objects.create(actor=self.request.user, action='delete', target=self.object)
return response
class PostDeleteView(LoginRequiredMixin, TenantScopedMixin, AuditedDeleteMixin, DeleteView):
model = PostThứ tự kế thừa quan trọng: mixin đứng trước, base view đứng sau. Python MRO duyệt trái → phải, nên LoginRequiredMixin phải ở đầu để chặn sớm trong dispatch.
Bẫy hay gặp khi mixin chồng nhau: 2 mixin cùng override một method mà không gọi super() thì một cái sẽ "ăn" mất cái còn lại, gây bug rất khó tìm. Khi MRO rối, in ClassName.__mro__ ra xem trật tự thực. Thường thì đây cũng là dấu hiệu nên gom logic vào service layer thay vì nhồi thêm mixin.