如何将Django执行人员主页视图转换为Django REST Framework实现
将Django视图转换为Django REST Framework版本的实现方案
一、创建对应的序列化器
首先为Customer模型编写DRF序列化器,用于将模型实例序列化为JSON格式:
# serializers.py from rest_framework import serializers from .models import Customer class CustomerSerializer(serializers.ModelSerializer): class Meta: model = Customer # 按需指定返回字段,或用'__all__'返回所有字段 fields = ['id', 'Pincode', 'Status', '其他业务所需字段']
二、构建DRF版本的视图
替换原ListView和LoginRequiredMixin,使用DRF的ListAPIView与权限类IsAuthenticated,复用原视图的业务逻辑:
# views.py from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from .models import Customer, ExcutiveRegistrationPincode from .serializers import CustomerSerializer class ExcutiveHomeAPIView(ListAPIView): serializer_class = CustomerSerializer permission_classes = [IsAuthenticated] # 对应原LoginRequiredMixin的登录校验 def get_queryset(self): # 复用原逻辑:获取当前执行员覆盖的邮编列表 pincodes = [ e.Covering_Pincode for e in ExcutiveRegistrationPincode.objects.filter( ExcutiveRegistration__user=self.request.user ).only('Covering_Pincode') ] # 返回符合条件的Customer查询集 return Customer.objects.filter(Pincode__in=pincodes, Status='Avaiable')
三、传递额外数据的两种常用方式
如果需要在响应中添加额外业务数据(如当前执行员信息、客户统计数等),可选择以下方式实现:
方式1:重写list方法自定义响应结构
def list(self, request, *args, **kwargs): queryset = self.get_queryset() serializer = self.get_serializer(queryset, many=True) # 构造额外数据 extra_data = { 'executive_name': request.user.excutiveregistration.First_name, 'total_available_customers': len(queryset), # 按需添加其他字段 } # 合并序列化数据与额外数据返回 response_data = { 'customers': serializer.data, 'business_info': extra_data } return Response(response_data)
方式2:通过序列化器上下文传递数据
先在视图中重写get_serializer_context,将额外数据传入序列化器:
def get_serializer_context(self): context = super().get_serializer_context() # 添加上下文数据 context['executive_info'] = { 'name': self.request.user.excutiveregistration.First_name, 'work_state': self.request.user.excutiveregistration.Work_State } return context
再在序列化器中通过self.context获取数据,甚至添加自定义字段:
class CustomerSerializer(serializers.ModelSerializer): executive_name = serializers.SerializerMethodField() def get_executive_name(self, obj): return self.context['executive_info']['name'] class Meta: model = Customer fields = ['id', 'Pincode', 'Status', 'executive_name']
附:原代码参考
models.py
from django.contrib.auth.models import AbstractUser from django.db import models # 补充原代码中未展示的选项定义 ID_CHOICES = [("Voter", "Voter ID")] Status_ = [('No Action', 'No Action'), ('Avaiable', 'Available')] class User(AbstractUser): ADDCHKS_ID = models.CharField(max_length=16, blank=True, null=True) is_active = models.BooleanField(default=False, blank=True, null=True) is_excutive = models.BooleanField(default=False, blank=True, null=True) class ExcutiveRegistration(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, null=True) # Personal Details First_name = models.CharField(max_length=100, null=True ,blank=True) Last_name = models.CharField(max_length=100, null=True ,blank=True) DOB = models.DateField(null=True ,blank=True) Fathers_name = models.CharField(max_length=100, null=True ,blank=True) Contact_number = models.IntegerField(null=True ,blank=True) Alt_Contact_number = models.IntegerField(null=True ,blank=True) # Current Address Pin_code_c = models.IntegerField(null=True ,blank=True) State_c = models.CharField(max_length=50, null=True ,blank=True) District_c = models.CharField(max_length=50, null=True ,blank=True) Taluk_c = models.CharField(max_length=50, null=True ,blank=True) Location_c = models.CharField(max_length=100, null=True ,blank=True) House_no_c = models.IntegerField(null=True ,blank=True) Street_c = models.CharField(max_length=100, null=True ,blank=True) # Permanent Address Pin_code_p = models.IntegerField(null=True, blank=True) State_p = models.CharField(max_length=50, null=True, blank=True) District_p = models.CharField(max_length=50, null=True, blank=True) Taluk_p = models.CharField(max_length=50, null=True, blank=True) Location_p = models.CharField(max_length=100, null=True, blank=True) House_no_p = models.IntegerField(null=True, blank=True) Street_p = models.CharField(max_length=100, null=True, blank=True) # Reference Family_reference_name = models.CharField(max_length=100, null=True, blank=True) Family_reference_conatact_number = models.IntegerField(null=True, blank=True) Neighbour_reference_name = models.CharField(max_length=100, null=True, blank=True) Neighbour_reference_contact = models.IntegerField(null=True, blank=True) # Document Proof ID_Proof_Document_Type = models.CharField( max_length=50, choices=ID_CHOICES, default="Voter", null=True, blank=True ) # Area Covered Work_State = models.CharField(max_length=50, null=True ,blank=True) Work_covering_district = models.CharField(max_length=50, null=True ,blank=True) Working_location = models.CharField(max_length=50, null=True ,blank=True) Status = models.CharField( max_length=50, choices=Status_, default='No Action', null=True, blank=True ) def __str__(self): return str(self.First_name) class ExcutiveRegistrationPincode(models.Model): ExcutiveRegistration = models.ForeignKey(ExcutiveRegistration, on_delete=models.CASCADE) Covering_Pincode = models.IntegerField(max_length=6)
原Django视图代码
from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import ListView from .models import Customer, ExcutiveRegistrationPincode class ExcutiveHomeView(LoginRequiredMixin, ListView): context_object_name = 'customers' template_name = 'accounts/excutive/excutive_home_page.html' def get_queryset(self, *args, **kwargs): pincodes = [ e.Covering_Pincode for e in ExcutiveRegistrationPincode.objects.filter( ExcutiveRegistration__user=self.request.user ).only('Covering_Pincode') ] return Customer.objects.filter(Pincode__in=pincodes, Status='Avaiable')
内容的提问来源于stack exchange,提问作者Harshith Kumara Kannan
相关产品推荐
相关产品推荐

