How to optimize the number of queries when using raw_id_fields in Django Admin

I have a data model as shown below:

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() 

And in the admin I have:

 class CandidateSkillInline(admin.TabularInline): model = CandidateSkill fields = ('skill', ) extra = 0 raw_id_fields = ('skill',) class CandidateAdmin(admin.ModelAdmin): model = Candidate fields = ('name',) inlines = [CandidateSkillInline] 

Each candidate can have many skills. The problem here is that on the change page for each inline query, one query will be used to get the skill ( SELECT β€’β€’β€’ FROM "skill" WHERE "skill"."id" = <id> ). If I add the skill field to CandidateSkillInline as read_only , there will be no additional requests. However, I would like to be able to add new elements to rows. The thing I tried:

1) Added an individual set of forms on CandidateSkillInline :

 class CandidateSkillInlineFormset(BaseInlineFormSet): def __init__(self, *args, **kwargs): super(CandidateSkillInlineFormset, self).__init__(*args, **kwargs) self.queryset = self.queryset.select_related('skill') 

2) Cancel get_queryset on line:

 def get_queryset(self, request): super(CandidateSkillInline, self).get_queryset(request).select_related('skill') 

3) Cancel get_queryset to CandidateAdmin :

 def get_queryset(self, request): return super(CandidateAdmin, self).get_queryset(request).prefetch_related('candidate_skills__skill') 

However, I still get a request for each skill. The only way that no requests are sent is when I set the skill to read_only_fields in CandidateSkillInilne. The question is, how can I select or pre-select skills in one request, and not one for each built-in?

+8
source share
1 answer

It seems that you are trying to implement your own ManyToManyField . Can you use ManyToManyField and inline instead? The admin has a beautiful widget with multiple choices.

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#working-with-many-to-many-models

+1
source

Source: https://habr.com/ru/post/1012755/


All Articles