我在Django的管理界面中遇到了一些性能问题& Postgres的。我已将其缩小到我的RecipeControl模型中针对每个IngredientInline执行的查询。配方中存在的成分越多,页面加载的时间就越长,因为似乎想要多次为IngredientInline加载查询集(大约2,000条记录)。
我确信解决方案是在加载页面之前以某种方式预先缓存查询集,但我对这是如何工作感到困惑,并且不知道这可能会导致什么样的问题在路上。我已经研究了prefetch_related vs select_related之间的区别,并试图同时使用两者,但在做任何一项时,似乎没有任何性能变化。我found this question但我也在使用管理界面,而不是写自己的观点。那么我是如何/哪个管理模块正确覆盖以产生所需的效果?谢谢你的帮助。
我的模型如下:
class RecipeControl(models.Model):
#recipe_name choice field needs to be a query set of all records containing "FG-Finished Goods"
recipe_name = models.ForeignKey(items.IngredientList, related_name='recipe_name', limit_choices_to={'category': 'FG'})
customer_recipe = models.ForeignKey(custmods.CustomerProfile, verbose_name='customer', related_name='customer_recipe')
ingredients = models.ManyToManyField(items.IngredientList, through='RecipeIngredients')
active_recipe = models.BooleanField(default=False)
active_by = models.CharField(max_length=64, editable=False)
revision = models.IntegerField(default=0)
last_updated = models.DateTimeField(auto_now_add=True, editable=False)
mixer_volume = models.DecimalField(verbose_name='Mixer Volume(L)', max_digits=16,decimal_places=3, blank=True, null=True)
fill_factor = models.DecimalField(verbose_name='Fill %', max_digits=6,decimal_places=2,blank=True,null=True)
def __str__(self):
return "%s" % (self.recipe_name)
class RecipeIngredients(models.Model):
recipe = models.ForeignKey(RecipeControl, related_name='recipe')
ingredient = models.ForeignKey(items.IngredientList, related_name='ingredient')
weight_tolerance = models.DecimalField(verbose_name="PPH Tolerance",max_digits=8, decimal_places=3, blank=True, null=False)
recipe_weight = models.DecimalField(verbose_name="PPH",max_digits=16, decimal_places=3, blank=True, null=True)
def __str__(self):
return "%s" % (self.ingredient)
我的admin.py文件:
class IngredientInline(admin.TabularInline):
model = RecipeIngredients
#prefetch_related = ('ingredient',)
readonly_fields = ('percentage', 'item_price','ext_price','SPG')
fieldsets = [(None,{'fields':[('ingredient','item_price','ext_price','SPG','percentage','weight_tolerance','recipe_weight')]})]
extra = 0
template = 'admin/recipes/recipeingredients/edit_inline/tabular.html'
class RecipeView(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.active_by = request.user.username
obj.save()
list_select_related = ['recipe_name', 'customer_recipe']
list_display = ['recipe_name','customer_recipe','active_recipe','last_updated','active_by']
list_display_links = ['recipe_name']
list_filter = ['active_recipe']
search_fields = ['recipe_name__name', 'recipe_name__item_code','customer_recipe__name']
readonly_fields = ('last_updated','active_by','batch_weight','calculated_batch', 'recipe_gravity')
fieldsets = [
('Recipe Information',{'fields': [('recipe_name','customer_recipe','active_recipe')]}),
('Audit Trail', {'fields': [('active_by','revision','last_updated')]}),
('Batch Weight Info',{'fields': [('batch_weight', 'mixer_volume', 'fill_factor','recipe_gravity', 'calculated_batch')]})
]
inlines = [IngredientInline]
答案 0 :(得分:1)
用户界面并不理想,但最快的解决方法是将raw_id_fields
用于任何具有多种可能性的外键。
class IngredientInline(admin.TabularInline):
model = RecipeIngredients
raw_id_fields = ['ingredients']
如果您需要更好的用户界面,可以查找外部包,例如django-select2。