2016-07-13 22 views
1

我有一个模型:Django的 - 在POST解析表单集数据是十分缓慢

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

您可以使用['django-debug-toolbar'](https://django-debug-toolbar.readthedocs.io/en/1.4/)来确定哪些查询花费最多时间,并且使用'EXPLAIN'。它还可以检测可能避免的潜在重复查询。 –

+0

如果您使用的是PyCharm,您可以在视图中设置断点并在调试模式下运行服务器。它可以从体面的调试器中得到任何东西,比如看变量和逐行运行代码。 –

+0

您是否使用了分析或记录时间来确定瓶颈是那些线?如果是这样,请更新您的问题,包括这些表的大小以及使用的索引 – e4c5

回答

1

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

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

Django Debug Toolbar example

要是你发现你有重复的查询,他们通常可使用select_related避免。

+0

非常有用,谢谢。侧面的问题:如果我正在使用测试服务器并在我的工作机器上作为调试进行此操作,那么我是否应该预计CPU时间膨胀?我从CPU面板获得10秒的请求周转时间。只是好奇有多少是便携式笔记本电脑试图做的一切。 –