代码之家  ›  专栏  ›  技术社区  ›  Bruno Francisco

对DRF使用延迟加载

  •  0
  • Bruno Francisco  · 技术社区  · 6 年前

    我想做一个简单的 lazy loading 使用Django Rest框架。 我有一个坚实的背景 Laravel 你可以像这样简单地使用它:

    Subscription::with('company')->paginate()
    

    但对于DRF我有问题。一家公司可以拥有 一次订阅 我的模型是这样定义的:

    单位

    class CompanyManager(BaseUserManager):
        def create_user(self, email, password=None):
            """
            Creates and saves a User with the given email and password
            """
            if not email:
                raise ValueError('Users must have an email address')
    
            user = self.model(
                email=self.normalize_email(email),
            )
    
            user.set_password(password)
    
            user.save(using=self._db)
    
            return user
    
    
    class Company(AbstractBaseUser):
        """
            Company refers to what we have referee in the official document as "Empresa Partner"
    
            Attributes:
                name: The name of the main company
                email: Email to contact the main company
                code: the code attributed to this company
        """
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
        email = models.EmailField(unique=True)
        username = models.CharField(blank=True, max_length=100)
        is_staff = models.BooleanField(blank=True, default=False)
        our_system_date = models.DateTimeField(auto_now=True)
    
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = []
    
        objects = CompanyManager()
    
        def __str__(self):
            return self.email
    

    订阅

    class Subscription(models.Model):
        """
        Subscriptions that references the plans and the companies
        :company:
            The owner of this subscription
    
        :plan:
            The plan this subscription is based on
    
        :starts:
            When the subscription starts
    
        :ends:
            When this subscription ends
        """
        company = models.ForeignKey(Company, on_delete=models.CASCADE)
        plan = models.ForeignKey(Plan, on_delete=models.CASCADE)
        starts = models.DateTimeField()
        ends = models.DateTimeField()
        created_at = models.DateTimeField(auto_now=True)
    

    我试过用 select_related 根据这个答案 What's the difference between select_related and prefetch_related in Django ORM? 但每次我向端点发出请求时,它都不会显示相关的 Company Subscription

    我是怎么用的 选择相关的 :

        def list(self, request, *args, **kwargs):
            queryset = Subscription.objects\
                .all().select_related('company')\
                .order_by('-created_at')
            page = self.paginate_queryset(queryset)
    
            if page is not None:
                serializer = SubscriptionSerializer(
                    page,
                    many=True,
                )
    
                return self.get_paginated_response(serializer.data)
    
    

    在我的 SubscriptionSerliazer :

    class SubscriptionSerializer(ModelSerializer):
        class Meta:
            model = Subscription
            fields = (
                'company',
                'plan',
                'starts',
                'ends',
                'created_at',
            )
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   Endre Both    6 年前

    如果要返回相关模型的字段而不仅仅是其主键,则需要为相关模型定义序列化程序(此处: CompanySerializer )并指示父序列化程序使用它:

    class SubscriptionSerializer(ModelSerializer):
        company = CompanySerializer()
    
        class Meta:
            model = Subscription
            fields = (
                'company',
                # ...
            )