2016-11-30 3 views
6

У меня есть модель данных, как показано ниже:Как оптимизировать количество запросов при использовании 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. Вопрос в том, как я могу выбрать или предварительно выбрать навыки в одном запросе, а не по одному для каждого встроенного?

+0

немного пояснение пожалуйста. Вы говорите: «У каждого кандидата может быть много навыков», но то, что моделируется здесь, - это отношение «Множество к многим» (без явного использования ManyToManyField Django). – e4c5

+0

@ e4c5 Я обновил модель для получения более подробных сведений. Мне нужно хранить «умение» для каждого навыка, а значит, нужно много-много – Nasir

+0

hm, единственное изменение, которое я вижу, - это поле имени, которое изменяется на уровень владения языком, что все еще делает его многотомным «сквозным» CandidateSkilll – e4c5

ответ