我已经看到了关于如何设置ModelMultipleChoiceField以使用自定义查询集的所有方法,我已经尝试过它们并且它们有效。但是,它们都使用相同的范例:查询集只是相同对象的筛选列表。
在我的情况下,我试图让管理员绘制一个多选表单,而不是使用用户名作为文本部分,我想使用我的帐户类中的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'
我认为这很容易,但它变成了几个小时的死胡同。有人想照亮一点吗?
答案 0 :(得分:1)
您可以使用自定义窗口小部件,覆盖其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
,但你可以试试。
答案 1 :(得分:0)
查询集需要是一个QuerySet,当你执行values_list时,你会得到一个列表,这样就无法工作。
如果您想更改模型的默认显示,只需覆盖__unicode__
即可。见http://docs.djangoproject.com/en/dev/ref/models/instances/#unicode
例如:
def __unicode__(self):
return u"%s for %s" % (self.name, self.user)
Django会在您要求它打印模型时使用__unicode__
。对于测试,您只需在shell中加载模型并执行print my_instance
。
答案 2 :(得分:0)
从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)
关键是放弃了查询集。一旦我使用固定的choices=
参数,一切正常。谢谢大家!