2012-04-17 122 views
3

如何更改Inline类中字段的选择?我不能在Inline中使用formfield_for_choice_field,那么要使用什么? 我必须在管理员中生成它,因为我需要通过请求。Django的管理员 - 如何改变内联的选择?

class YourInline(admin.StackedInline): # or TabularInline 
    model = YourModelName 

    def formfield_for_choice_field(self, db_field, request=None, **kwargs): 
     if db_field.name == 'YOUR_FIELD_NAME': 
      kwargs['choices'] = (('', '---------'), ('1', 'Choice1'), ('2', 'Choice2')) 
     return db_field.formfield(**kwargs) 

好运

+0

内联使用简单的表单,因此您可以使用该表单进行任何操作。你究竟在做什么? – ilvar 2012-04-18 04:05:13

+0

我需要更改内联1字段的选择列表。我不能在模型中这样做,因为我必须使用请求来检查管理员中的用户权限和注册模型。是否可能以某种方式将请求传递给窗体,然后在自定义内联窗体中对该字段进行一些修改? – tunarob 2012-04-18 06:27:49

+0

它是你的领域的一个外键? – eos87 2012-04-18 16:33:22

回答

4

如果你的领域是IntegerField或Charfield与选择属性,你可以在内嵌类像这样覆盖formfield_for_choice_field方法eos87的答案。但这只是一个部分解决方案。保存时,由于将原始模型的选项用于验证,因此会出现验证错误。要解决这个问题,请将此函数添加到您的模型中:

def clean_fields(self, exclude=None): 
    exclude.append('YOUR_FIELD_NAME') # we will do our own validation on this field 
    super(YOUR_MODEL, self).clean_fields(exclude = exclude) 

    value = self.YOUR_FIELD_NAME 
    if value and not self.validChoice(value): 
     msg = 'Select a valid choice. %s is not one of the available choices.' 
     errors = {''YOUR_FIELD_NAME'': ([msg % value])} 
     raise ValidationError(errors) 

def validChoice(self, value): 
    # add your validation code here 
+0

我尝试过,但保存和模型中的字段没有选择参数它不能被保存,我得到__init__错误。当我在模型中放置空选项并使用您给出的解决方案时,出现错误,所选的选项是错误的:/ – tunarob 2012-04-18 20:33:55

+1

您必须至少放置一个选项,例如, ((1,'1'),),那么上面的方法将覆盖那个选择。 – eos87 2012-04-18 20:54:35

+1

明天我会检查一下。我发现您的解决方案与文档中显示的解决方案有一个区别(https://docs.djangoproject.com/en/1.3//ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_choice_field)。您返回 'db_field.formfield(** kwargs)'当字段发现,而文档说只返回 'super(MyModelAdmin,self).formfield_for_choice_field(db_field,request,** kwargs)'。 希望它会工作:) – tunarob 2012-04-18 21:16:52

0

在我的情况下,表单选项必须填写,希望能帮助任何人。

# admin.py 
class YourInlineForm(forms.ModelForm): 
    class Meta: 
     fields = '__all__' 
     model = YourModelName 
     widgets = { 
      'level': forms.widgets.Select(
       choices = (
        (0,'A'), 
        (1,'B'), 
        (2,'C'), 
       ), 
      ) 
     } 

# admin.py 
class YourInline(admin.StackedInline): # or TabularInline 
    model = YourModelName 
    form = YourInlineForm 

    def formfield_for_choice_field(self, db_field, request=None, **kwargs): 
     if db_field.name == 'YOUR_FIELD_NAME': 
      kwargs['choices'] = (('', '---------'), ('1', 'Choice1'), ('2', 'Choice2')) 
     return db_field.formfield(**kwargs) 
相关问题