предотвращение дублирования sql с помощью встроенного набора форм в django 3.0.5 - PullRequest
1 голос
/ 01 мая 2020

У меня проблема с фабрикой встроенных форм в django 3.0.5. у меня есть такие модели:

class Resume(models.Model):
    user = models.ForeignKey(User, verbose_name=_('User'), on_delete=models.CASCADE)
    website = models.URLField(verbose_name=_('Web Site'), blank=True, null=True)
    ...

class Expertise(models.Model):
    name = models.CharField(_('name'), max_length=100)
    ...

class ResumeExpertise(models.Model):
    resume = models.ForeignKey(Resume, on_delete=models.CASCADE, related_name='resume_expertise')
    expertise = models.OneToOneField(Expertise, on_delete=models.CASCADE, verbose_name=_('Expertise'), related_name='resume_expertise_item')
    score = models.PositiveSmallIntegerField(_('Score'))

    def __str__(self):
        return self.expertise.name

в этом случае пользователь должен отредактировать форму. я использовал встроенную фабрику formset. my forms.py:

class ResumeForm(forms.ModelForm):
    class Meta:
        model = Resume
        fields = ('website',)

    def __init__(self, *args, **kwargs):
        super(ResumeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = True
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-3 create-label'
        self.helper.field_class = 'col-md-9'
        self.helper.layout = Layout(
            Div(
                Field('website'),
                Fieldset('Expertise',
                         Formset('expertise')),
                HTML("<br>"),
                ButtonHolder(Submit('submit', 'save')),
            )
        )

class ResumeExpertiseForm(forms.ModelForm):
    class Meta:
        model = ResumeExpertise
        fields = ('expertise', 'score')


ResumeExpertiseFormSet = inlineformset_factory(Resume, ResumeExpertise, form=ResumeExpertiseForm, fields=['expertise', 'score'], extra=1, can_delete=True)

для представлений я использовал представления на основе классов, например:

class ResumeEdit(LoginRequiredMixin, UpdateView):
    model = Resume
    template_name = "user/resume_form.html"
    form_class = ResumeForm
    success_url = reverse_lazy('user:profile')

    def get_object(self, queryset=None):
        return Resume.objects.get(user=self.request.user)

    def get_context_data(self, *args, **kwargs):
        context = super(ResumeEdit, self).get_context_data(**kwargs)
        context['title'] = _('Edit Resume')
        if self.request.POST:
            context['expertise'] = ResumeExpertiseFormSet(self.request.POST, instance=self.object)
        else:
            context['expertise'] = ResumeExpertiseFormSet(instance=self.object)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        expertise = context['expertise']
        with transaction.atomic():
            form.instance.user = self.request.user
            self.object = form.save()
            if expertise.is_valid():
                expertise.instance = self.object
                expertise.save()
        return super(ResumeEdit, self).form_valid(form)

Моя проблема в том, что когда я загружаю форму ResumeEdit в браузере, debug_toolbar показывает:

SELECT ••• FROM `user_expertise`
 26 similar queries. Duplicated 26 times.

Я новичок в фабрике встроенных форм и так растерялся. что я сделал не так? Есть ли способ предотвратить это дубликаты?

...