2013-07-23 115 views
0

我工作的一個RSVP應用與模型這樣:選擇題現場保存

class Guest(models.Model): 
    profile = models.ForeignKey(UserProfile) 
    ... 
    invite_list = models.ManyToManyField(GuestList, through='RSVP') 


class RSVP(models.Model): 
    guestlist = models.ForeignKey(GuestList) 
    guest = models.ForeignKey(Guest, related_name='rsvp') 
    ... 

而且我試圖創建一個多選場表單,允許用戶選擇客人添加到RSVP。我正在使用jQuery將多個選擇增強爲2個框,其中所選項目將顯示在右側的框中。

在forms.py和使用crispy_forms

class RSVPSelectGuestForm(forms.Form):  
    guests = forms.MultipleChoiceField() 

    def __init__(self, *args, **kwargs): 
     profile = kwargs.pop('profile', None) 
     guestlist_pk = kwargs.pop('guestlist_pk', None) 
     super(RSVPSelectGuestForm, self).__init__(*args, **kwargs) 
     self.helper = FormHelper() 
     self.helper.layout = Layout(
      Field('guests', 
       id='guests-multiple-select', 
      ), 
      FormActions(
       Submit('submit', 'Save'), 
      ),  
     ) 
     self.fields['guests'].choices = [(obj.id, str(obj)) for obj in Guest.objects.filter(profile=profile)] 
     self.fields['guests'].initial = [(obj.guest_id) for obj in RSVP.objects.filter(guestlist_id=guestlist_pk)] 

我能夠用上面的代碼正確渲染選擇多個元素。我將視圖中的kwargs傳遞給get_form_kwargs上的表單。

現在的問題是要以有效的方式添加/刪除客人從RSVP表的方式。我很猶豫,因爲我不能決定我所提出的解決方案之間的下方繼續前進:

  1. 過程中的每個UI事件發生時間的形式 - 當用戶選擇了一個客人,就立即加入桌子;當用戶取消選擇一個用戶時,該訪客將從RSVP表中刪除。如果客人數量增加,這可能會導致大量的SQL讀/寫操作。

  2. 沒有被保存,直到提交表單 - 從POST數據,我將創建所選選項的字典,它在形式加載,任何新行添加和缺失行卸下的狀態比較從桌子上。這隻需要2個SQL操作。

任何人都可以幫助建議一個很好的解決方法或更好的想法來解決這個問題嗎?我的建議中有沒有可能忽略的問題?

回答

0

我決定與解決方案二去,現在,因爲它是更容易實現。在表格中添加以下方法,當保存表格時,會創建並比較兩組數據。 [這很容易python的方式]然後,我們可以使用1查詢每個批量創建或批量刪除。我還沒有在大型數據集上測試過這些代碼。

def add_guests(self, added): 
    RSVP.objects.bulk_create([ 
     RSVP(guestlist_id=self.guestlist_pk, guest_id=guest_pk) 
     for guest_pk in added 
    ]) 

def remove_guests(self, removed): 
    RSVP.objects.filter(guestlist_id=self.guestlist_pk, 
     guest_id__in=removed).delete() 

def save(self): 
    data = self.cleaned_data 

    initial_data = set(self.initial_data) 
    new_data = set([int(i) for i in data['guests']]) 

    added = new_data - initial_data 
    removed = initial_data - new_data 

    if added: 
     self.add_guests(added) 
    if removed: 
     self.remove_guests(removed) 

任何改進建議?