Django - 在POST中解析formset数据非常缓慢

时间:2016-07-13 14:55:34

标签: django formset

我有一个模特:

class IP(models.Model):
    address     = models.GenericIPAddressField()
    fqdn        = models.CharField(max_length=255, blank=True)
    description = models.CharField(max_length=1000, blank=True)
    available   = models.BooleanField(default=True)
    reserved    = models.BooleanField(default=False)
    network     = models.ForeignKey(Network, on_delete=models.CASCADE)
    customer    = models.ForeignKey(Customer,on_delete=models.CASCADE, blank=True, null=True)

和表格:

class IPForm(ModelForm):
    id          = forms.CharField(widget=forms.HiddenInput())
    address     = forms.CharField(disabled=True,
                                  widget=forms.TextInput(attrs={'class':'     form-control'}))
    fqdn        = forms.CharField(widget=forms.TextInput(attrs={'class':'     form-control'}), required=False)
    description = forms.CharField(widget=forms.TextInput(attrs={'class':'     form-control ip_description'}), required = False)
    customer    = forms.ModelChoiceField(queryset=Customer.objects.all().order_by('name'), widget=forms.Select(attrs={'class':'form-control'}), required=False)
    reserved    = forms.BooleanField(widget=forms.CheckboxInput(attrs=    {'class':'checkbox'}), required=False)
    class Meta:
        model = IP
        exclude = ['available', 'network']

以及使用modelformset_factory:

创建formset的视图
def ipDetailView(request, ipIDs=None):
    ipformset = modelformset_factory(IP, form=IPForm, extra=0)
    if request.method == 'POST':
        if len(request.POST.getlist('ip')):
            #we were sent a list of IP IDs to edit
            if 'clear_btn' in request.POST:
                #just remove the fqdn/description of the posted IPs
                ips = IP.objects.filter(id__in=request.POST.getlist('ip'))
                for ip in ips:
                    ip.fqdn = ''
                    ip.description = ''
                    ip.available = True
                    ip.save()
                return redirect ('iplistview', networkID=ips[0].network.id)
            else:
                #post the forms so the IPs can be edited
                formset =     ipformset(queryset=IP.objects.filter(id__in=request.POST.getlist('ip')))
                return render (request, 'ipmanager/ipdetailview.html',     {'formset' : formset})
        else:
            #we were sent a set of IP forms to commit changes for
            formset = ipformset(request.POST)
            if formset.is_valid():
                instances = formset.save()
                return redirect ('iplistview',     networkID=instances[0].network.id)
            else:
                 return render(request, 'ipmanager/ipdetailview.html',
                                                {
                                                'formset'      : formset,
                                                })

    else:
        network = IP.objects.filter(id=ipIDs)[0].network
        formset = ipformset(queryset=IP.objects.filter(id=ipIDs))
        return render (request, 'ipmanager/ipdetailview.html', {'formset' :     formset, 'network' : network})

我的问题是,我提交IP表单的POST部分需要5-8秒才能提交,无论我是提交1个IP还是20个。代码对于该部分非常简单:

     formset = ipformset(request.POST)
     if formset.is_valid():
        instances = formset.save()

我甚至不确定如何弄清楚为什么这么长时间。我没有多对多的关系似乎在困扰其他类似的问题。我该如何找出造成这种缓慢的原因?

1 个答案:

答案 0 :(得分:1)

您可以使用django-debug-toolbar来确定哪些查询花费最多时间,原始SQL语句,调用代码的位置以及EXPLAIN

它还可以检测可以避免的潜在重复查询。

Django Debug Toolbar example

如果您发现重复查询,通常可以使用select_related来避免查询。