1. <i id='FT8Xt'><tr id='FT8Xt'><dt id='FT8Xt'><q id='FT8Xt'><span id='FT8Xt'><b id='FT8Xt'><form id='FT8Xt'><ins id='FT8Xt'></ins><ul id='FT8Xt'></ul><sub id='FT8Xt'></sub></form><legend id='FT8Xt'></legend><bdo id='FT8Xt'><pre id='FT8Xt'><center id='FT8Xt'></center></pre></bdo></b><th id='FT8Xt'></th></span></q></dt></tr></i><div id='FT8Xt'><tfoot id='FT8Xt'></tfoot><dl id='FT8Xt'><fieldset id='FT8Xt'></fieldset></dl></div>
    2. <small id='FT8Xt'></small><noframes id='FT8Xt'>

    3. <legend id='FT8Xt'><style id='FT8Xt'><dir id='FT8Xt'><q id='FT8Xt'></q></dir></style></legend>

        <bdo id='FT8Xt'></bdo><ul id='FT8Xt'></ul>
    4. <tfoot id='FT8Xt'></tfoot>

      Django 管理员内联:select_related

      时间:2023-08-30

      <small id='Zl3FX'></small><noframes id='Zl3FX'>

        <tbody id='Zl3FX'></tbody>
        <bdo id='Zl3FX'></bdo><ul id='Zl3FX'></ul>

      • <legend id='Zl3FX'><style id='Zl3FX'><dir id='Zl3FX'><q id='Zl3FX'></q></dir></style></legend>

              <i id='Zl3FX'><tr id='Zl3FX'><dt id='Zl3FX'><q id='Zl3FX'><span id='Zl3FX'><b id='Zl3FX'><form id='Zl3FX'><ins id='Zl3FX'></ins><ul id='Zl3FX'></ul><sub id='Zl3FX'></sub></form><legend id='Zl3FX'></legend><bdo id='Zl3FX'><pre id='Zl3FX'><center id='Zl3FX'></center></pre></bdo></b><th id='Zl3FX'></th></span></q></dt></tr></i><div id='Zl3FX'><tfoot id='Zl3FX'></tfoot><dl id='Zl3FX'><fieldset id='Zl3FX'></fieldset></dl></div>

                <tfoot id='Zl3FX'></tfoot>
                本文介绍了Django 管理员内联:select_related的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                在带有模型的 Python 3.4.1 上使用 Django 1.8:

                Using Django 1.8 on Python 3.4.1 with models:

                class Product(models.Model):
                    name = models.CharField(max_length=255)
                    # some more fields here
                
                    def __str__(self):
                        return self.name
                
                
                class PricedProduct(models.Model):
                    product = models.ForeignKey(Product, related_name='prices')
                    # some more fields here
                
                    def __str__(self):
                        return str(self.product)
                
                class Coming(models.Model):
                    # some unimportant fields here
                
                
                class ComingProducts(models.Model):
                    coming = models.ForeignKey(Coming)
                    priced_product = models.ForeignKey(PricedProduct)
                    # more unimportant fields
                

                和下面的 admin.py:

                and the following admin.py:

                class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline):
                    model = ComingProducts
                
                
                class ComingAdmin(admin.ModelAdmin):
                    inlines = [ComingProductsInline]
                

                当然,我在对数据库进行多次查询时遇到了问题:我对列表中的每个项目都有一个查询,对每一行都有一个查询.所以,有 100 个项目我得到 100 ^ 2 个查询.我已经用 缓存查询集解决了每一行的查询问题Django 表单中 ModelChoiceField 或 ModelMultipleChoiceField 的选择但我仍然对 str 方法有问题.我尝试了以下方法:

                Of course, i have a problem with multiply queries to database: i have a query for each item in list and a query for each line. So, having 100 items i get 100 ^ 2 queries. I've solved the problem with queries for each line with Caching queryset choices for ModelChoiceField or ModelMultipleChoiceField in a Django form But i still having problem with str method. I've tried the following:

                1) 将 prefetch_related 添加到 ComingAdmin:

                1) adding prefetch_related to ComingAdmin:

                def get_queryset(self, request):
                    return super(ComingAdmin, self).get_queryset(request). 
                    prefetch_related('products__product')
                

                2) 将 select_related 添加到 ComingProductInline:

                2) adding select_related to ComingProductInline:

                def get_queryset(self, request):
                    return super(ComingProductsInline, self).get_queryset(request). 
                    select_related('priced_product__product')
                

                3) 为内联定义自定义表单并将 select_related 添加到字段查询集:

                3) Defining custom form for inline and adding select_related to field queryset:

                 class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline):
                     model = ComingProducts
                     form = ComingProductsAdminForm
                
                 class ComingProductsAdminForm(ModelForm):
                     def __init__(self, *args, **kwargs):
                              super(ComingProductsAdminForm, self).__init__(args, kwargs)
                              self.fields['priced_product'].queryset = PricedProduct.objects.all(). 
                              select_related('product')
                
                     class Meta:
                         model = ComingProducts
                         fields = '__all__'
                

                4) 定义自定义表单集:

                4) Defining a custom formset:

                 class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline):
                     model = ComingProducts
                     formset = MyInlineFormset
                
                 class MyInlineFormset(BaseInlineFormSet):
                     def __init__(self, data=None, files=None, instance=None,
                             save_as_new=False, prefix=None, queryset=None, **kwargs):
                        super(MyInlineFormset, self).__init__(data, files, instance,
                                                          save_as_new, prefix, queryset, **kwargs)
                        self.queryset = ComingProducts.objects.all(). 
                        prefetch_related('priced_product__product')
                

                5) 前 4 种方法的不同组合

                5) Different combinations for previous 4 methods

                没有任何帮助:每次调用 str 对 PricedProduct 都会使 Django 执行对 Product 表的查询.所有这些方法都在 stackoverflow 上提到过,但是它们处理了 ModelAdmin,并且对 Inline 没有帮助.我错过了什么?

                And nothing helps: each call of str for PricedProduct makes Django to perform a query for Product table. All of these methods were mentioned on stackoverflow, but they treated ModelAdmin, and do not help with Inline. What do i miss?

                推荐答案

                formset 解决方案确实对我有用,但方法略有不同:

                The formset solution does work for me, but with a slightly different approach:

                class MyInlineFormset(BaseInlineFormSet):
                    def __init__(self, *args, **kwargs):
                        super(MyInlineFormset, self).__init__(*args, **kwargs)
                        self.queryset = self.queryset.prefetch_related('priced_product__product')
                

                BaseInlineFormSet 类为您过滤查询集,您需要获取过滤后的查询集并添加预取.使用您的表单集实现(all() 查询集),您将获得不相关的 ComingProduct 对象,并且渲染时间可能太长.当它是过滤后的查询集时,它会非常快速地呈现.

                The BaseInlineFormSet class filters the queryset for you, and you need to take that filtered queryset and add the prefetch. With your formset implementation (the all() queryset) you get unrelated ComingProduct objects and it probably takes much too long to render. When it's the filtered queryset it renders very quickly.

                这篇关于Django 管理员内联:select_related的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:Django 错误.不能分配必须是实例 下一篇:Django模型:两个类之间的相互引用以及在python中无法使用前向声明

                相关文章

              1. <i id='855Q0'><tr id='855Q0'><dt id='855Q0'><q id='855Q0'><span id='855Q0'><b id='855Q0'><form id='855Q0'><ins id='855Q0'></ins><ul id='855Q0'></ul><sub id='855Q0'></sub></form><legend id='855Q0'></legend><bdo id='855Q0'><pre id='855Q0'><center id='855Q0'></center></pre></bdo></b><th id='855Q0'></th></span></q></dt></tr></i><div id='855Q0'><tfoot id='855Q0'></tfoot><dl id='855Q0'><fieldset id='855Q0'></fieldset></dl></div>

                <small id='855Q0'></small><noframes id='855Q0'>

                  • <bdo id='855Q0'></bdo><ul id='855Q0'></ul>
                  <legend id='855Q0'><style id='855Q0'><dir id='855Q0'><q id='855Q0'></q></dir></style></legend>
                  <tfoot id='855Q0'></tfoot>