2011-07-26 71 views

回答

44

那麼如果你想讓它只需要在管理的效果,而不是全局,那麼你可以創建一個自定義ModelChoiceField子類,使用在自定義ModelForm,然後設置相關的管理類中使用您的自定義表單。 以具有FK由@Enrique使用的Person型號的例子:

class Invoice(models.Model): 
     person = models.ForeignKey(Person) 
     .... 

class InvoiceAdmin(admin.ModelAdmin): 
     form = MyInvoiceAdminForm 


class MyInvoiceAdminForm(forms.ModelForm): 
    person = CustomModelChoiceField(queryset=Person.objects.all()) 
    class Meta: 
      model = Invoice 

class CustomModelChoiceField(forms.ModelChoiceField): 
    def label_from_instance(self, obj): 
     return "%s %s" % (obj.first_name, obj.last_name) 
+0

還有一件事:爲什麼PLUS圖標不顯示在我的選擇輸入旁邊?沒有被覆蓋的字段有 - 它是我改變的 - 不是 – robos85

8

https://docs.djangoproject.com/en/1.3/ref/models/instances/#unicode

class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 

    def __unicode__(self): 
     return u'%s %s' % (self.first_name, self.last_name) 

你必須定義要在模型的的Unicode方法來顯示內容(這裏是ForeignKey的)。

問候,

+1

我知道這一點,但我想在其他地方的管理員中僅更改一處,不應該改變該方法對我不利。 – robos85

+0

@ robos85:查看我的答案,找到您要找的答案。你也應該更新你的問題。 –

35

這樣做的另一種方法(有用的,當你改變你的查詢集):

class MyForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['user'].queryset = User.objects.all() 
     self.fields['user'].label_from_instance = lambda obj: "%s %s" % (obj.last_name, obj.first_name) 

「用戶」是名你想重寫的字段。此解決方案爲您提供了一個優勢:您也可以覆蓋queryset(例如,您希望User.objects.filter(username__startswith ='a'))

聲明:解決方案發現於http://markmail.org/message/t6lp7iqnpzvlt6qp並經過測試。

9

的Django的新版本支持這一點,它可以與gettext的翻譯:

models.ForeignKey(ForeignStufg, verbose_name='your text') 
+0

在https://docs.djangoproject.com/en/dev/topics/db/models/#verbose-field-names上有記錄。 – jarmod

+5

這實際上解決了被問到的問題。 –

0

我剛剛發現,你可以用另一個查詢集替換查詢集,甚至刪除了查詢集和一個選項列表替換。我在change_view中這樣做。

在這個例子中,我讓家長設置的返回值,然後從中抓住特定領域,並設置.choices:

def change_view(self, request, object_id, form_url='', extra_context=None): 
     #get the return value which includes the form 
     ret = super().change_view(request, object_id, form_url, extra_context=extra_context) 

     # let's populate some stuff 
     form = ret.context_data['adminform'].form 

     #replace queryset with choices so that we can specify the "n/a" option 
     form.fields['blurb_location'].choices = [(None, 'Subscriber\'s Location')] + list(models.Location.objects.filter(is_corporate=False).values_list('id', 'name').order_by('name')) 
     form.fields['blurb_location'].queryset = None 

     return ret 
1

的替代第一個答案:

class InvoiceAdmin(admin.ModelAdmin): 

    class CustomModelChoiceField(forms.ModelChoiceField): 
     def label_from_instance(self, obj): 
      return "%s %s" % (obj.first_name, obj.last_name) 

    def formfield_for_foreignkey(self, db_field, request, **kwargs): 
     if db_field.name == 'person': 
      return self.CustomModelChoiceField(queryset=Person.objects) 

     return super(InvoiceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) 
相關問題