Проблема с передачей набора запросов к фреймворку Django rest

#django #django-rest-framework

Вопрос:

У меня есть проблема в течение нескольких дней, но я так и не нашел никакого решения, я пробовал другой подход, но безуспешно. Я хочу передать несколько запросов в одном и том же представлении или пути.

 @api_view(['GET'])
def getProduct(request, pk):
    product = Product.objects.get(_id=pk)
    related = Product.objects.filter(category=product.category).exclude(_id=pk).order_by('?')[:4]
    print(related)
    serializer = ProductSerializer(product, many=False)
    return Response(serializer.data)
    
 

Я хочу передать связанный набор запросов к продукту, который связан здесь в том же представлении. В первом разделе я покажу сведения о продукте, который работает, а в следующем разделе я хочу показать связанные, но теперь как я могу это применить??

У меня есть какое-то решение, которое подсказало мне пойти за сериализаторами и измениться там. Но я так не думаю, потому что я там пробовал, но как это возможно. Так что у кого-нибудь есть лучшее решение. мой связанный объект имеет тот же сериализатор, что и productserializer. но в конечном счете это сопутствующий продукт.

#это мой класс сериализатора

 class ProductSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField(read_only=True)
    class Meta:
        model = Product
        fields = '__all__'

    def get_user(self, obj):
        user = obj.user
        serializer = VendorSerializer(user, many=False)
        return serializer.data
 

#это моя модель продукта

 class Product(models.Model):

    brand_choices = [

        ('TVS', 'TVS'),
        ('Hero', 'Hero'),
        ('Yamaha', 'TVS'),
        ('Minister', 'Minister'),
        ('Walton', 'Walton'),
        ('Suzuki', 'Suzuki'),

    ]

    user = models.ForeignKey(Vendor, on_delete=models.CASCADE)
    name = models.CharField(max_length=220)
    image = models.ImageField(null=True, blank=True)
    brand = models.CharField(max_length=220, null=True, blank=True, choices=brand_choices)
    category = models.ForeignKey(Subcategory, on_delete=models.CASCADE)
    description = models.TextField(max_length=10000)
    rating = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
    numReviews = models.IntegerField(null=True, blank=True, default=0)
    old_price = models.DecimalField(max_digits=11, decimal_places=2)
    discount = models.IntegerField(blank=True, null=True)
    price = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
    countInStock = models.IntegerField(blank=True, null=True, default=0)
    createdAt = models.DateTimeField(auto_now_add=True)
    short_description = models.CharField(max_length=2000, blank=True, null=True)
    brandImage = models.ImageField(null=True, blank=True)
    isStorm = models.BooleanField(blank=True, null=True, default=False)
    _id = models.AutoField(primary_key=True, editable=False)
    

    def save(self, *args, **kwargs):
        self.price = Decimal(self.old_price * (100 - self.discount) / 100)
        return super(Product, self).save(*args, **kwargs)
    

    class Meta:
        ordering = ['-createdAt']


    def __str__(self):
        return self.name
 

and this is my updated serializer code

 class ProductWithRelatedSerializer(ProductSerializer):
    related = serializers.SerializerMethodField(read_only=True)
    
    class Meta:
        model = Product
        fields = '__all__'

    def get_related(self, obj, pk):
        product = Product.objects.all()
        related = Product.objects.filter(category=
            product.category).exclude(_id=pk).order_by('?')[:4].select_related('Product')[:4]
        ps = ProductSerializer(related, many=True)
        return ps.data
 

this is my view

 @api_view(['GET'])
def getProduct(request, pk):
    product = Product.objects.get(_id=pk)
    # related = Product.objects.filter(category=product.category).exclude(_id=pk).order_by('?')[:4]
    # print(related)
    serializer = ProductWithRelatedSerializer(product, many=False)
    return Response(serializer.data)
    
 

updated serializerr

 class ProductWithRelatedSerializer(ProductSerializer):
    related = serializers.SerializerMethodField(read_only=True)
    
    class Meta:
        model = Product
        fields = '__all__'

    def get_related(self, obj):
        product = Product.objects.all()
        related = Product.objects.filter(category=
            product.category).exclude(_id=obj.pk).order_by('?')[:4].select_related('Product')[:4]
        ps = ProductSerializer(related, many=True)
        return ps.data
 

#страница сведений о продукте, которую я использовал, пожалуйста, проверьте и помогите мне

 import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Image, ListGroup, Form, Button, Card, Modal } from 'react-bootstrap'
import Rating from '../components/Rating'
import Loader from '../components/Loader'
import Message from '../components/Message'
import products from '../products'
import { useDispatch, useSelector } from 'react-redux'
import { listProductDetails } from '../actions/productActions'
import { productDetailsReducer } from '../reducers/productReducers'
import {InlineShareButtons} from 'sharethis-reactjs';
import {InlineFollowButtons} from 'sharethis-reactjs';
import { addToCart, removeFromCart } from '../actions/cartActions'
import { LinkContainer } from 'react-router-bootstrap'
import { Container} from 'react-floating-action-button'


function ProductScreen({ match, history }) {
    
    const cart = useSelector(state => state.cart)
    const { cartItems } = cart

    const removeFromCartHandler = (id) => {
        dispatch(removeFromCart(id))
    }

    const checkoutHandler = () => {
        history.push('/login?redirect=shipping')
    }

    const [show, setShow] = useState(false);
  
    const handleClose = () => setShow(false);

    const handleShow = () => setShow(true);

    const [qty, setQty] = useState(1)

    const dispatch = useDispatch()

    const productDetails = useSelector(state => state.productDetails)
    const {loading, error, product, related} = productDetails

    useEffect(() => {
        dispatch(listProductDetails(match.params.id))
    }, [dispatch, match])

    const addToCartHandler = () => {
        history.push(`/cart/${match.params.id}?qty=${qty}`)
    }
    
    return (
        <div>
            <Container>
             
                <Button
                    tooltip="Cart"
                    icon=""
                    rotate={true}
                    onClick={handleShow}
                    className="btn btn-primary btn-circle btn-xl"><i className="fas fa-shopping-cart" style={{fontSize:23}}><sup className='shanto'>{cartItems.length}</sup></i></Button>
            </Container>

            <Link to='/' className='btn btn-light my-3'><strong>Go Back</strong></Link>
            {loading ?
                <Loader />
                : error
                    ? <Message variant='danger'>{error}</Message>
                :(
                            <Row>
                                <Col md={6}>
                                    
                                    <Image src={product.image} alt={product.name} fluid />
                                </Col>
                                
                               
                            
                                <Col md={3}>
                                    <ListGroup variant="flush">
                                        <ListGroup.Item>
                                            <h3>{product.name}</h3>
                                        </ListGroup.Item>

                                        <ListGroup.Item>
                                            <h3>{related.id}</h3>
                                        </ListGroup.Item>


                                        <ListGroup.Item>
                                            Old Price: <strong className="tk">৳</strong><del> {product.old_price} </del>
                                        </ListGroup.Item>

                                        <ListGroup.Item >
                                            Discount: <b>{product.discount}%</b>
                                        </ListGroup.Item>

                                        <ListGroup.Item>
                                            Price: <strong className="tk">৳</strong> {product.price}
                                        </ListGroup.Item>


                                        <ListGroup.Item style={{color: 'red'}}>
                                            <p><b>{product.short_description}</b></p> 
                                        </ListGroup.Item>


 
 

Ответ №1:

Вы можете реализовать ProductWithRelatedSerializer приложение, которое использует ProductSerializer для сериализации продуктов. Таким образом, мы выделяем подкласс из ProductSerializer :

 class ProductWithRelatedSerializer(ProductSerializer):
    related = serializers.SerializerMethodField(read_only=True)

    def get_related(self, obj):
        related = Product.objects.filter(
            category_id=obj.category_id
        ).exclude(_id=obj.pk).order_by('?').select_related('user')[:4]
        ps = ProductSerializer(related, many=True)
        return ps.data 

.select_related(…) [Django-doc] не является необходимым, но повысит эффективность get_user метода ProductSerializer для соответствующих продуктов.

Таким образом, это вернет ответ, который выглядит следующим образом:

 {
    /* … */
    "user": {
        …
    },
    related: [
         { "user": { … } },
         { "user": { … } },
         { "user": { … } },
         { "user": { … } }
    ]
} 

Комментарии:

1. Тогда как я буду просматривать его во внешнем интерфейсе??

2. data.related это список серийных продуктов. Таким образом, он добавляет дополнительное поле related к «внешнему» продукту, и вы можете перечислять по списку, чтобы отобразить связанные продукты, точно так же, как вы отображаете выбранный продукт.

3. Я имею в виду, каким будет мой файл представления, и в этом сериализаторе говорится, что product и pk не определены, поэтому я сделал запрос product = Product.objects.all (), а затем вызвал объект product, и для pk я передаю его в качестве параметра, но он говорит, что отсутствует один позиционный аргумент

4. @SohanurRahmanShanto16209570: вы заменяете serializer = ProductSerializer(product, many=False) в своем представлении на serializer = ProductWithRelatedSerializer(product, many=False)

5. брат, большое тебе спасибо за твои усилия. Но это дает мне ошибку, например, продукт не найден, а позиционный аргумент pk отсутствует