3

我使用的是django-ajax-selects,這是一個免費的django應用程序,提供jQuery自動完成功能。django-ajax-selecting應用程序:如果數據庫中尚未存在一個新對象,我該如何創建一個新對象?

我得到它的工作 - 即它是自動完成我想要的表單字段。

class Skater(models.Model): 
    name = models.CharField(max_length=64) 
    surname = models.CharField(max_length=64) 
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 

class Partnership(models.Model): 
    female_partner = models.ForeignKey(Skater, limit_choices_to = {'gender': FEMALE}, related_name='female_partner_set') 
    male_partner = models.ForeignKey(Skater, limit_choices_to = {'gender': MALE}, related_name='male_partner_set') 

我希望用戶能夠把一個名字和姓成female_partner和male_partner:但是我有一個問題...我在其中添加了合作對象數據庫中的ModelForm使用它即使這樣的Skater對象不存在,我也希望創建該對象。我如何去做這件事?我不能把代碼放在窗體的保存方法中,因爲這個字段不會被驗證(它不是一個有效的Skater)。

EDIT 1: 添加在多個代碼...

形式:

class PartnershipAddForm(forms.ModelForm): 
    female_partner = AutoCompleteSelectField('female_skater',required=True) 
    male_partner = AutoCompleteSelectField('male_skater',required=True) 

    class Meta: 
     model = Partnership 

settings.py:

AJAX_LOOKUP_CHANNELS = { 
    'female_skater' : ('skaters.lookups', 'FemaleLookup'), 
    'male_skater' : ('skaters.lookups', 'MaleLookup'), 
} 

lookups.py(MaleLookup是相同的除了性別=男性):

class FemaleLookup(object): 

    def get_query(self,q,request): 
     """ return a query set. you also have access to request.user if needed """ 
     return Skater.objects.filter(Q(gender=FEMALE) & (Q(name__istartswith=q) | Q(surname__istartswith=q))) 

    def format_item(self,skater): 
     """ simple display of an object when it is displayed in the list of selected objects """ 
     return unicode(skater) 

    def format_result(self,skater): 
     """ a more verbose display, used in the search results display. may contain html and multi-lines """ 
     return "%s<br/>" % unicode(skater) 

    def get_objects(self,ids): 
     """ given a list of ids, return the objects ordered as you would like them on the admin page. 
      this is for displaying the currently selected items (in the case of a ManyToMany field) 
     """ 
     return Skater.objects.filter(pk__in=ids).order_by('name','surname') 

回答

3

AutoCompleteSelectField持有的對象,而不是文字,這就是爲什麼我一直有「需要」的錯誤(爲什麼丹尼爾的解決方案不工作)的ID。值變量是空的,因爲不存在的Skater沒有id。

我不確定這是做到這一點的最佳方式,但我最終使用了AutoCompleteField而不是AutoCompleteSelectField。 AutoCompleteField保存文本,但它不會爲我創建一個Skater對象。

代碼:

class PartnershipAddForm(forms.ModelForm): 
    female_partner = AutoCompleteField('female_skater',required=True) 
    male_partner = AutoCompleteField('male_skater',required=True) 

    class Meta: 
     model = Partnership 

    def save(self): 
     partners = [self.cleaned_data['female_partner'], 
        self.cleaned_data['male_partner']] 
     name = ['',''] 
     surname = ['',''] 
     for i in [0,1]: 
      name[i],surname[i] = get_name_surname(partners[i]) 
     partners = [None,None] 
     partners_created = [None,None] 
     gender = [FEMALE,MALE] 
     for i in [0,1]:   
      partners[i],partners_created[i] = Skater.objects.get_or_create(
              name=name[i], 
              surname=surname[i], 
              gender=gender[i] 
             ) 

     partnership, created = Partnership.objects.get_or_create(
            female_partner=partners[0], 
            male_partner=partners[1], 
           ) 
     return partnership 
+0

+1使用AutoCompleteField,唯一的問題是,當使用窗體進行編輯時,該字段預先填充了id而不是文本值。 – 2017-03-31 10:30:12

0

我們可以看看你的表單看起來像什麼嗎?我認爲你需要像在你的ModelForm中重寫save()方法,所以它首先保存了female_partner和male_partner,然後保存了表單實例(又名Parntership實例)。

+0

除非表單驗證我不能叫form.save()在視圖中,並沒有在我的使用情況進行驗證(我得到「領域中所需的」)。 – 2010-01-24 22:01:19

+0

爲什麼不重寫ModelForm中的form.is_valid方法,所以它首先調用Skater對象上的save()。 – buckley 2010-01-25 15:45:31

+0

我找不到覆蓋is_valid()方法的任何文檔。看着它在Django的代碼,它看起來像這樣: 高清is_valid(個體經營)「。 返回true如果表格沒有錯誤,否則,假如果 被忽略的錯誤,返回False 。‘ 「」’ 「 返回self.is_bound而不是bool(self.errors) 不要以爲我應該重寫它。 – 2010-01-25 17:30:07

2

它看起來像你需要從ajax選擇子類AutoCompleteSelectField並覆蓋它的clean方法。

def clean(self, value): 
    if value: 
     lookup = get_lookup(self.channel) 
     objs = lookup.get_objects([value]) 
     if objs: 
      return objs[0] 
     else: 
      firstname, surname = value.split(" ") 
      gender = self.channel.split("_")[0] 
      new_skater = Skater(name=firstname, surname=surname, gender=gender) 
      return new_skater 
    else: 
     if self.required: 
      raise forms.ValidationError(self.error_messages['required']) 
     return None 
+0

你肯定是正確的,這是我應該重寫的方法(對於那個已經讓我轉發的原因+1),但這不是完整的解決方案 - 問題在方法中較早。我從來沒有進入塊的「如果價值」部分。還沒有想出如何繞過這個: -/ – 2010-01-30 18:10:05

相關問題