代码之家  ›  专栏  ›  技术社区  ›  Daniel Quinn

将ModelMultipleEchoiceField的查询集动态设置为自定义记录集

  •  1
  • Daniel Quinn  · 技术社区  · 15 年前

    我已经了解了如何设置ModelMultipleEchoiceField以使用自定义查询集的所有方法,并且我已经尝试了它们,它们都可以工作。但是,它们都使用相同的范例:查询集只是相同对象的过滤列表。

    在我的示例中,我试图让管理员绘制一个多选择表单,该表单不使用用户名作为的文本部分,而是使用 name 来自我的帐户类的字段。

    以下是我的详细资料:

    # models.py
    class Account(models.Model):
        name = models.CharField(max_length=128,help_text="A display name that people understand")
        user = models.ForeignKey(User, unique=True) # Tied to the User class in settings.py
    
    class Organisation(models.Model):
        administrators = models.ManyToManyField(User)
    
    
    # admin.py
    from django.forms import ModelMultipleChoiceField
    from django.contrib.auth.models import User
    
    class OrganisationAdminForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
            from ethico.accounts.models import Account
            self.base_fields["administrators"] = ModelMultipleChoiceField(
                queryset=User.objects.all(),
                required=False
            )
            super(OrganisationAdminForm, self).__init__(*args, **kwargs)
    
    class Meta:
        model = Organisation
    

    不过,这行得通 queryset 在上面绘制带有 Account.name 财产和 User.id 财产。这不起作用:

    queryset=Account.objects.all().order_by("name").values_list("user","name")
    

    失败原因如下:

    'tuple' object has no attribute 'pk'
    

    我想这很容易,但它变成了几个小时的死角。有人想开灯吗?

    3 回复  |  直到 15 年前
        1
  •  1
  •   sebpiq    15 年前

    您可以使用自定义小部件,覆盖其 render 方法。以下是我为文本字段所做的操作:

    class UserToAccount(forms.widgets.TextInput):
        def render(self, name, value, attrs=None):
            if isinstance(value, User) :
                value = Account.objects.get(user=value).name
            return super (UserToAccount, self).render(name, value, attrs=None)        
    

    当然,使用 widget 管理员字段的参数,以便使用自定义小部件。 我不知道它是否能适应 select 但是你可以试试。

        2
  •  0
  •   knutin    15 年前

    查询集需要是一个查询集,当你做值列表时,你会得到一个列表,这样就不会工作。

    如果要更改模型的默认显示,只需覆盖 __unicode__ . 见 http://docs.djangoproject.com/en/dev/ref/models/instances/#unicode

    例如:

    def __unicode__(self):
        return u"%s for %s" % (self.name, self.user)
    

    Django将使用 阿伊努埃德埃希 当你要求它打印模型时。为了测试,您可以在shell中加载一个模型,然后 print my_instance .

        3
  •  0
  •   Daniel Quinn    15 年前

    我从Seppiq排队,终于弄明白了:

    class OrganisationAdminForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
    
            from django.forms import MultipleChoiceField
            from ethico.accounts.models import Account
    
            self.base_fields["administrators"] = MultipleChoiceField(
                choices=tuple([(a.user_id, a.name) for a in Account.objects.all().order_by("name")]),
                widget=forms.widgets.SelectMultiple,
                required=False
            )
    
            super(OrganisationAdminForm, self).__init__(*args, **kwargs)
    
        class Meta:
            model = Organisation
    
    
    class OrganisationAdmin(admin.ModelAdmin):
        form = OrganisationAdminForm
    
    
    admin.site.register(Organisation, OrganisationAdmin)
    

    键完全放弃了查询集。有一次我带着一个固定的 choices= 参数,一切正常。谢谢大家!