如何在 DRF 中查询与外键相关的父模型和子模型中的所有字段?以及如何将分页应用于同一个字典?

How to query all the fields in parent as well as child model related with a foreign key in DRF ? and how to apply pagination to the same dict?

我在这个项目中有 3 个模型


class products(models.Model):  
    product_id = models.CharField(max_length=10, blank=False, null=False, primary_key=True)
    name = models.CharField(max_length=20, blank=False)
    description = models.TextField(blank=True, null=True)
    userslikedproduct = models.ManyToManyField(UserAccount, blank=True)

    def __str__(self):
        return self.product_id

class productReviews(models.Model):
    review_id = models.CharField(max_length=10, blank=False, null=False, primary_key=True)
    product = models.ForeignKey(products, related_name='reviews', on_delete=models.CASCADE)
    user = models.ForeignKey(UserAccount, related_name='users', on_delete=models.CASCADE)
    review_desc = models.TextField(blank=True, null=True)
    review_rating = models.IntegerField(choices=RATING, null=True)
    date_added = models.DateTimeField(verbose_name='date_added', auto_now_add=True)

class ReviewImage(models.Model):
    review = models.ForeignKey(productReviews, related_name='review_images', on_delete=models.CASCADE)
    image = models.ImageField(null=True, blank=True, upload_to="/images/")

我想获取与产品 ID 相关的所有评论以及评论图片。

我试过使用

Query1 = productReviews.objects.all().filter(product=product).values().order_by('-date_added')

Query2 = ReviewImage.objects.filter(review__product__product_id=product).values_list('review', 'image')

Query1 的结果是所有没有图像的对象 Query2 返回没有评论对象的所有图像和评论 ID

如何获取某一特定产品的所有评论以及评论图片?

在能够访问外键对象之前,这是我的 views.py 文件

class productReviews(APIView):

    def post(self, request, *args, **kwargs):
        product = request.data.get('product', False)
        result = productReviews.objects.all().filter(product=product).values().order_by('-date_added')
        
        # Set up Pagination
        p = Paginator(result, 2)
    
      
        page = request.GET.get('page')
        

        try:
            page_obj = p.get_page(page)  
        except PageNotAnInteger:
            
            page_obj = p.page(1)
        except EmptyPage:
            
            page_obj = p.page(p.num_pages)
        context = {'page_obj': page_obj}


        print(context)
        samp_obj = page_obj.object_list
        print(samp_obj)
        a = page_obj.has_next()

        print(a)
  

       

        context = str(context)
   
        return Response({

                         'data': samp_obj,
                         'has_next_page': a,
                         
                         })

从我的 views.py 文件中使用它后

class productReviews(APIView):

    def post(self, request, *args, **kwargs):
        product = request.data.get('product', False)
        
        
        
        reviews = productReviews.objects.all().filter(product=product).order_by('-date_added')
        print(reviews)
        
        reviews_as_dict = reviews.values()
        for review, review_dict in zip(reviews, reviews_as_dict):
            # Now you can get review images assigned to each review like this
            review_images = review.review_images.all()

            # Update the review_dict to include the review_image data
            review_dict['review_images'] = review_images.values()
            
        print(review_dict)


        # Set up Pagination
        p = Paginator(review_dict, 2)
    
      
        page = request.GET.get('page')
        

        try:
            page_obj = p.get_page(page)  
        except PageNotAnInteger:
            
            page_obj = p.page(1)
        except EmptyPage:
            
            page_obj = p.page(p.num_pages)
        context = {'page_obj': page_obj}


        print(context)
        samp_obj = page_obj.object_list
        
        a = page_obj.has_next()

       
       

        
   
        return Response({
                         'data': samp_obj,
                         'has_next_page': a,
                         
                         })

但是现在我无法在分页中使用dict对象

如何应用分页?

我认为您不需要使用 valuesvalues_list。这使您的对象成为 Python 字典或列表。

我想您可能正在寻找这样的东西:

# To get all reviews
reviews = product.reviews.order_by('date_added')

# To get all reviews as Python dicts
reviews_as_dict = reviews.values()

for review, review_dict in zip(reviews, reviews_as_dict):
  # Now you can get review images assigned to each review like this
  review_images = review.review_images.all()

  # Update the review_dict to include the review_image data
  review_dict['review_images'] = review_images.values()

这应该给你一个字典列表,看起来应该是这样的:

[
  {
     ... other review attributes,
     review_images: [
        {
          ... ReviewImage attributes
        }, ...
     ]
  }, ...
]

然而,这似乎是不必要的。如果您将此数据传递给模板,您可以将第一个 reviews 变量添加到上下文中并在模板中使用它,如下所示:

<div>
  {% for review in reviews %}
    <h1>Review {{ review.review_rating }}</h1>
    <small>Description {{ review.review_desc }}</small>
    
    <h3>Review images for this review</h3>
    <ul>
      {% for review_image in review.review_images.all %}
         <li><img src="{{ review_image.image.url }}"></img></li>
      {% endfor %}
    </ul>
  {% endfor %}
</div>

希望这能回答您的问题。