2016-07-13 62 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秒的請求週轉時間。只是好奇有多少是便攜式筆記本電腦試圖做的一切。 –