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

Python 将ModelMultipleChiceField的查询集动态设置为自定义记录集,python,django,django-admin,Python,Django,Django Admin,我已经看过了所有关于如何设置ModelMultipleChiceField以使用自定义queryset的说明,我已经尝试过了,它们都很有效。然而,它们都使用相同的范例:queryset只是相同对象的筛选列表 在我的例子中,我试图让管理员绘制一个多选表单,该表单不使用用户名作为的文本部分,而是使用account类中的name字段 以下是我所得到的资料的细目: # models.py class Account(models.Model): name = models.CharField(m

我已经看过了所有关于如何设置ModelMultipleChiceField以使用自定义queryset的说明,我已经尝试过了,它们都很有效。然而,它们都使用相同的范例:queryset只是相同对象的筛选列表

在我的例子中,我试图让管理员绘制一个多选表单,该表单不使用用户名作为的文本部分,而是使用account类中的
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'

我原以为这很容易,但却变成了几个小时的死胡同。有人想解释一下吗?

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

如果要更改模型的默认显示,只需覆盖
\uuuuuunicode\uuuuu
。看

例如:

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

只要您要求Django打印模型,Django就会使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。对于测试,您只需在shell中加载一个模型,然后执行
打印我的\u实例

查询集需要是一个查询集,当您执行值列表时,您会得到一个列表,这样就不起作用了

如果要更改模型的默认显示,只需覆盖
\uuuuuunicode\uuuuu
。看

例如:

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

只要您要求Django打印模型,Django就会使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。为了进行测试,您只需在shell中加载一个模型并执行
打印我的\u实例

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

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)        
当然,为了使用自定义小部件,请使用administrator字段的
小部件
参数。

我不知道它是否能适应
选择
,但你可以试试。

你可以使用自定义小部件,覆盖它的
渲染
方法。以下是我对文本字段所做的操作:

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)        
当然,为了使用自定义小部件,请使用administrator字段的
小部件
参数。

我不知道它是否适合于
选择
,但您可以尝试。

从sebpiq获取一个队列,我设法找到了它:

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)

关键是完全放弃queryset。一旦我使用了一个固定的
choices=
参数,一切都正常了。谢谢大家

从sebpiq排队,我设法弄明白了:

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)

关键是完全放弃queryset。一旦我使用了一个固定的
choices=
参数,一切都正常了。谢谢大家

我会完全这样做,除了在这种情况下,有问题的模型是用户,我不控制它。您知道我将如何调整User类的unicode属性吗?我将完全这样做,只是在本例中,所讨论的模型是User,我不控制它。您知道如何调整用户类的unicode属性吗?