У меня есть модель данных, как показано ниже:Как оптимизировать количество запросов при использовании raw_id_fields в Django администратора
class Candidate(models.Model):
name = models.CharField()
class Skill(models.Model):
name = models.CharField()
class CandidateSkill(models.Model):
candidate = models.ForeignKey(Candidate)
skill = models.ForeignKey(Skill, related_name='candidate_skills')
proficiency = models.CharField()
И в админке у меня есть:
class CandidateSkillInline(admin.TabularInline):
model = CandidateSkill
fields = ('skill',)
extra = 0
raw_id_fields = ('skill',)
class CandidateAdmin(admin.ModelAdmin):
model = Candidate
fields = ('name',)
inlines = [CandidateSkillInline]
Каждый кандидат может иметь много навыков , Проблема здесь в том, что на странице изменений для каждого встроенного запроса будет использоваться один запрос для получения навыка (SELECT ••• FROM "skill" WHERE "skill"."id" = <id>
). Если я добавлю поле skill
в CandidateSkillInline
как read_only
, то дополнительных запросов не будет. Однако я хотел бы иметь возможность добавлять новые элементы в строки. Вещь я пробовал:
1) Добавлен пользовательский formset к CandidateSkillInline
:
class CandidateSkillInlineFormset(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
super(CandidateSkillInlineFormset, self).__init__(*args, **kwargs)
self.queryset = self.queryset.select_related('skill')
2) Переопределение get_queryset
на инлайн:
def get_queryset(self, request):
super(CandidateSkillInline, self).get_queryset(request).select_related('skill')
3) замещают в get_queryset
на CandidateAdmin
:
def get_queryset(self, request):
return super(CandidateAdmin, self).get_queryset(request).prefetch_related('candidate_skills__skill')
Однако все же я получаю запрос для каждого навыка. Единственный способ, по которому запросы не отправляются, - это когда я установил skill
в read_only_fields
в CandidateSkillInilne. Вопрос в том, как я могу выбрать или предварительно выбрать навыки в одном запросе, а не по одному для каждого встроенного?
немного пояснение пожалуйста. Вы говорите: «У каждого кандидата может быть много навыков», но то, что моделируется здесь, - это отношение «Множество к многим» (без явного использования ManyToManyField Django). – e4c5
@ e4c5 Я обновил модель для получения более подробных сведений. Мне нужно хранить «умение» для каждого навыка, а значит, нужно много-много – Nasir
hm, единственное изменение, которое я вижу, - это поле имени, которое изменяется на уровень владения языком, что все еще делает его многотомным «сквозным» CandidateSkilll – e4c5