You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:36:40