#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 отсутствует