Django:在 Ajax 搜索结果中传递 prefetch_lated _set.all()

发布于 2025-01-13 04:40:09 字数 2380 浏览 4 评论 0原文

我已经用 Ajax 实现了一个表搜索产品,并且运行良好。

但现在,我想动态构建我的表,考虑到我的仓库数量可以增加。

search.js

data.forEach((item) => {

                        const newName = (item.nom).slice(0, 30) + "...";
                        tableBody.innerHTML += `
                        <tr>
                            <th><a href="{% url 'product-update' ${item.id} %}">${item.sku}</a></th>
                            <td>${item.etat__etat}</td>
                            <td class="small">${newName}</td>
                            <td>${item.famille__nom}</td>
                            <td>${item.mageid}</td>
                            <td>${item.adresse}</td>

models.py (我需要一套女巫模型)

class SstStock(models.Model):
    warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
    product = models.ManyToManyField(Produit)
    qty = models.IntegerField()
    last_update = models.DateTimeField(default=timezone.now)

views.py

def search_product2(request):
    if request.method == 'POST':
        search_str = json.loads(request.body).get('searchText')
        products = Produit.objects.filter(sku__icontains=search_str) | Produit.objects.filter(
            nom__icontains=search_str) | Produit.objects.filter(mageid__icontains=search_str)

        data = products.values(
            'id',
            'sku',
            'nom',
            
            [...]

            'sststock',

            [...]
            'cau_cli',
            'maxsst2',
        )

        return JsonResponse(list(data), safe=False)

直接在模板中我可以这样做:

template

{% for produit in produits %}
    {{ produit.sku}}<br>
    {% for sst in produit.sststock_set.all %}
    <span>{{sst.warehouse.code}} - {{ sst.qty }}</span><br>
    {% endfor %}
    <br>
{% endfor %}

但我找不到在 JsonResponse 中传递 sststock_set.all() 的方法。我在其中得到了一个“sststock”值,但它只包含该集合的最后一个值,而不是整个集合的数组/字典。

console.log()

qty: 7
sku: "ACP863"
sststock: 68095

68095 是我的集合的最后一个 ID。 更糟糕的是,当我尝试在 ForEach 产品中获取 item.sststock 时,在我的 JS 中,它返回未定义

有什么想法吗?

I've implemented a table search product with Ajax and it works well.

But now, I want to build dynamically my table taking in account the number of my warehouses can be increase.

search.js

data.forEach((item) => {

                        const newName = (item.nom).slice(0, 30) + "...";
                        tableBody.innerHTML += `
                        <tr>
                            <th><a href="{% url 'product-update' ${item.id} %}">${item.sku}</a></th>
                            <td>${item.etat__etat}</td>
                            <td class="small">${newName}</td>
                            <td>${item.famille__nom}</td>
                            <td>${item.mageid}</td>
                            <td>${item.adresse}</td>

models.py (model for witch I need a set)

class SstStock(models.Model):
    warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
    product = models.ManyToManyField(Produit)
    qty = models.IntegerField()
    last_update = models.DateTimeField(default=timezone.now)

views.py

def search_product2(request):
    if request.method == 'POST':
        search_str = json.loads(request.body).get('searchText')
        products = Produit.objects.filter(sku__icontains=search_str) | Produit.objects.filter(
            nom__icontains=search_str) | Produit.objects.filter(mageid__icontains=search_str)

        data = products.values(
            'id',
            'sku',
            'nom',
            
            [...]

            'sststock',

            [...]
            'cau_cli',
            'maxsst2',
        )

        return JsonResponse(list(data), safe=False)

Directly in template I could do :

template

{% for produit in produits %}
    {{ produit.sku}}<br>
    {% for sst in produit.sststock_set.all %}
    <span>{{sst.warehouse.code}} - {{ sst.qty }}</span><br>
    {% endfor %}
    <br>
{% endfor %}

But I couldn't find the way to pass the the sststock_set.all() in the JsonResponse. I got well a "sststock" value in it but it contains only the last value of the set instead of an array/dict of the whole set.

console.log()

qty: 7
sku: "ACP863"
sststock: 68095

68095 is the last ID of my set.
Worse, when I try to get item.sststock in the ForEach product, in my JS, it returns Undefined.

Any idea please ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵性 2025-01-20 04:40:09

找到了使用序列化器应用@WillemVanOnsem建议的方法。

首先,我的第一次错误战争应用ManyToMany而不是ForeignKey:

product = models.ManyToManyField(Produit)

之后,我设置了一个序列化器来检索不同的股票(warehouse_id + qty)并将其添加到产品模型(带有“source”参数):

serializers.py

from rest_framework import serializers
from .models import Produit, SstStock


class StockSearchSerializer(serializers.ModelSerializer):
    class Meta:
        model = SstStock
        fields = '__all__'
        fields = ['warehouse_id', 'qty']


class ProductSearchSerializer(serializers.ModelSerializer):

    sststock = StockSearchSerializer(source='sststock_set', many=True)

    class Meta:
        model = Produit
        fields = '__all__'

最后,我在视图中使用带有“many=True”的序列化程序,并返回其结果,该结果将由我的搜索页面上的 JS 处理:

views.py

def search_product(request):
    if request.method == 'POST':
        search_str = json.loads(request.body).get('searchText')
        products = Produit.objects.prefetch_related(
            Prefetch('sststock_set',
                     SstStock.objects.select_related('warehouse'))
                     ).filter(sku__icontains=search_str) | Produit.objects.filter(
            nom__icontains=search_str) | 
            Produit.objects.filter(mageid__icontains=search_str)
        
        serializer = ProductSearchSerializer(products, many=True)
        data = serializer.data
        return JsonResponse(list(data), safe=False)

如下希望,股票数组添加到 json 响应

在此处输入图像描述

Found the way to apply @WillemVanOnsem advice with serializer.

Before all, my first error war to apply ManyToMany instead of ForeignKey on:

product = models.ManyToManyField(Produit)

After, I have set a serializer that retrieves the different stocks (warehouse_id + qty) and adds it to the Product model (with "source" parameter):

serializers.py

from rest_framework import serializers
from .models import Produit, SstStock


class StockSearchSerializer(serializers.ModelSerializer):
    class Meta:
        model = SstStock
        fields = '__all__'
        fields = ['warehouse_id', 'qty']


class ProductSearchSerializer(serializers.ModelSerializer):

    sststock = StockSearchSerializer(source='sststock_set', many=True)

    class Meta:
        model = Produit
        fields = '__all__'

To finish, I use the serializer with "many=True" in the view and return its result that will be handled by JS on my search page:

views.py

def search_product(request):
    if request.method == 'POST':
        search_str = json.loads(request.body).get('searchText')
        products = Produit.objects.prefetch_related(
            Prefetch('sststock_set',
                     SstStock.objects.select_related('warehouse'))
                     ).filter(sku__icontains=search_str) | Produit.objects.filter(
            nom__icontains=search_str) | 
            Produit.objects.filter(mageid__icontains=search_str)
        
        serializer = ProductSearchSerializer(products, many=True)
        data = serializer.data
        return JsonResponse(list(data), safe=False)

And as wished, stocks array is added in the json response

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文