2017-07-26 21 views
0

我有一個應用程序,用戶可以在其中註冊他們的公司,然後從列表中選擇一些設置。公司和服務都是不同的模式。Django - TemplateView中的複選框和ManytoMany關係

class Company(models.Model): 
    name = models.CharField(max_length=100) 
    (...) 

class Service(models.Model): 
    name = models.CharField(max_length=100) 
    linked_companies = ManyToManyField(Company, blank=True) 

我要的是有服務的大名單,他們的名字背後的複選框,這樣業主可以迅速選擇他想要連接到他的模型的服務。這曾經是通過管理界面完成的,但由於受歡迎的需求,這個功能被移到了「前臺」。

問題是,我不知道如何將它融入迄今爲止我們一直使用的傳統(通用)視圖/表單組合中,因爲涉及到兩種不同的模型。

我想要一個更自定義的解決方案,但已經打到了牆上,我想知道你是否可以幫助我。我已經創建了一個應該顯示服務列表和「保存」按鈕的html頁面。

<form action="." method="POST" class="post-form">{% csrf_token %} 
     <ul> 
     {% recursetree services %} 
      <li> 
       <label><input type="checkbox" name='service' value={{ node.pk }}><h3>{{ node.name }}</h3></label> 
       {% if not node.is_leaf_node %} 
        <ul class="children"> 
         {{ children }} 
        </ul> 
       {% endif %} 
      </li> 
     {% endrecursetree %} 
     </ul> 

     <button type="submit" class="save btn btn-default">Add Selected 
     </button> 
</form> 

我使用下面的ModelForm:

class FacetForm(forms.ModelForm): 
    class Meta: 
     model = Services 
     fields = ['linked_tenants', 'name'] 

     widgets = { 
      'linked_tenants' : CheckboxSelectMultiple() 
     } 

此HTML頁面似乎工作打算,顯示了他們的名字後複選框服務的一個長長的清單。 但是,我無法創建函數視圖。連同collegue下面創建視圖

類FacetList(TenantRootedMixin,TemplateView):

def get_context_data(self, **kwargs): 
    d = super(ServiceList, self).get_context_data(**kwargs) 
    d['services'] = Services.objects.all() 
    d['current_company'] = self.context.company.id 
    return d 

def form_valid(self, *args, **kwargs): 
    return super(ServiceList, self).form_valid(*args, **kwargs) 

這種觀點工作在某種意義上說,它顯示了所有的相關信息(與複選框)。如果我更改查詢以按「公司ID」過濾服務。該視圖也可以按需要工作。

我所遇到的問題是圍繞着'保存'這個事實。崩潰程序,拋出以下錯誤。

'super' object has no attribute 'post' 

我們的計劃工作主要是通過通用classbased意見和modelforms,所以我們必須與創建自己的定製解決方案relativly經驗有限。我自己估計的問題似乎是雙重的:

  1. 的觀點可能是不正確的配置來處理「後」的數據
  2. 值得懷疑的是,如果該數據將被事後處理到數據庫中。

雖然'sollution'目前有缺陷,我們正在尋找正確的方向嗎?我們是否有正確的方式來解決我們的問題?

Regards

回答

1

我相信你是在正確的軌道上。我建議的是不要害怕擺脫普遍的觀點,轉向更加自定義的解決方案(即使您對此沒有經驗。)

是在我腦海中會如下第一個例程:

  • 收集所有用戶已檢查到一個列表從request.POST
  • 更新相應的對象的M2M領域包含的ID這些新的ID。
  • 保存前面提到的對象。

[編輯]

有一件事我有從request.POST收集ID的麻煩。你能否提供一個關於如何做到這一點的例子?

當然,從您的HTML文件中我看到您正在使用name=service創建輸入。這使我相信,你可以這樣做:

ids = request.POST.get('service') 

而是教你如何釣魚,而不是給你一條魚,你應該儘量簡單:

print request.POST.items() 

這將返回並打印到控制檯從你的表單發佈到你的視圖函數的所有內容。使用這個來確定你是否從模板獲得了一個id列表到服務器。如果沒有,您可能需要重新評估您在模板中構建表單的方式。

+0

謝謝您的迴應! 我一直在繼續研究它,並準備好了半功能原型。我遇到麻煩的一件事是從request.POST收集ID。你能否提供一個關於如何做到這一點的例子? – Jasper

+0

@Jasper看到我上面的編輯。 – marcusshep

1

你的第一點是正確的:TemplateView沒有定義「post」方法,這就是爲什麼當你調用super().form_valid時你會得到錯誤信息。您必須自己定義它或使用具有可以覆蓋的後處理方法的CBV(例如UpdateView)

而且我也相信您的第二點是正確的。

您需要使用UpdateView才能使用內置功能(或CreateView)。

我有一個類似的問題需要解決(從前端的多對多字段中選擇值),我最終只是「手動」,因爲我無法使它與CBV一起工作。 「通過手」 =>從形式解析值,更新數據庫,返回的HttpResponse

你可能想看看ModelFormSets: https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#model-formsets

希望這有助於! Alex