2017-08-08 25 views
1

我有一個名爲Keyword的模型和一個名爲Statement的模型,並且我一直在自定義用於添加或更改語句的表單。每個Keyword對象與Statement對象都有m2m(多對多)關係,並且我希望用戶能夠選擇要關聯的關鍵字。 m2m字段的默認控件在我的情況下沒有用處,因爲有很多關鍵字對象,所以我需要比這更好的東西。我使用了FilteredSelectMultiple小部件以獲得我需要的調整。django爲我的自定義管理員表單添加一個綠色加號爲內聯?

這是代碼。

在admin.py

class KeywordInline(admin.TabularInline): 
     model = Keyword.statement.through 
    class StatementAdmin(admin.ModelAdmin): 
     list_display = ('statement_id', 'title', 'author', 'released_by', 'issue_date', 'access', 'full_text',) 
     list_filter = (StatementListFilter, 'released_by', 'issue_date', 'access',) 
     search_fields = ('statement_id', 'title', 'author', 'issue_date',) 
     inlines = [ KeywordInline,] 

在forms.py

class StatementForm(forms.Modelform): 
     statement_keywords = forms.ModelMultipleChoiceField(
      queryset=Keyword.objects.all(), 
      required=False, 
      widget=FilteredSelectMultiple(
       verbose_name='Keywords Associated with Statement', 
       is_stacked=False 
      ) 
     ) 
     class Meta: 
      model = Statement 
     def __init__(self, *args, **kwargs): 
      super(StatementForm, self).__init__(*args, **kwargs) 
      if self.instance.pk: 
       self.fields['statement_keywords'].initial = self.instance.keyword_set.all() 

     def save(self, commit=True): 
      statement = super(StatementForm, self).save(commit=False) 
      if commit: 
      statement.save() 
      if statement.pk: 
       statement.keyword_set = self.cleaned_data['keyword'] 
      self.save_m2m() 

    return statement 

所以現在我有一個filter_horizo​​ntal菜單我的內聯,就像我想要的。但有一個問題:沒有加號可以添加新的關鍵字。

我知道RelatedFieldWidgetWrapper是解決這個問題所必需的,我發現了很多人使用它的例子。但是,我一直無法找到一個適合我的情況。我現在最直接的問題是試圖在「rel」參數中插入一些東西。 「rel」參數通常定義了「涉及到的兩個模型的關係」,這個流行的示例實現脫離了這個問題:http://dashdrum.com/blog/2012/07/relatedfieldwidgetwrapper/

我不知道如何表示這個關係,也不知道如何指示它,因爲我是使用內聯。所以我實際上並沒有使用名爲「關鍵字」的字段,我正在對KeywordStatement之間的m2m關係進行反向查找。所以我不知道用什麼名字來描述這種關係。

我發現的所有例子並沒有真正談到在這種情況下該怎麼做。大多數例子很容易從一個模型中獲得感興趣的領域,然後獲得它的類型或關係,但是通過內聯模型和反向關係,我不一定這樣做。

+0

你嘗試設置'extra'和'max_num' Inn的內聯? –

+0

還沒有。我會在一瞬間,但是......這些屬性在這方面會做什麼? –

+0

'extra'定義默認情況下將顯示多少額外的內聯。 'max_num'限制內聯的數量。因此,如果您的默認值「max_num」等於或小於「extra」的默認值,則不能添加額外的內聯。我的問題是由您的modelForm引起的,可能不是解決方案 - 但請嘗試一下。 –

回答

0

我設法讓生活更加完美,可以通過一個多對多的關係和一個內聯模型的自定義小部件,就像您所描述的那樣。

this answerthis post啓發這裏是用我的模型,因爲你不提供您的問題models.py,你也有你的代碼這個時候─信息額外-unnecessary結果。

models.py

class MasterModel(models.Model): 
    pass 


class ThirdModel(models.Model): 
    pass 


class InlineModel(models.Model): 
    ''' 
     It should also be working with a ForeignKey 
     but I have not tested it. 
    ''' 
    master_key = models.OneToOneField(MasterModel) 
    the_field = models.ManyToManyField(ThirdModel) 

forms.py

from django.contrib.admin import site as admin_site 
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper 


class InlineModelForm(forms.Modelform): 
    the_field = forms.ModelMultipleChoiceField(
     queryset=ThirdModel.objects.all(), 
     required=False, 
     widget=(
      <the_custom_widget with attributes etc> 
     ) 
    ) 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.fields['the_field'].widget = (
      RelatedFieldWidgetWrapper( 
       self.fields['the_field'].widget, 
       self.instance._meta.get_field('the_field').rel,    
       admin_site, 
      ) 
     ) 

    class Meta: 
     model = InlineModel 
     fields = '__all__' 

admin.py:

class InlineModelAdminInline(admin.TabularInline): 
    model = InlineModel 
    form = InlineModelForm 


@admin.register(MasterModel) 
class MasterModelAdmin: 
    inlines = (InlineModelAdminInline,) 


@admin.register(InlineModel) 
class InlineModelAdmin: 
    form = InlineModelForm 


@admin.register(ThirdModel) 
class ThirdModelAdmin: 
    pass 
相關問題