2010-05-17 47 views
1

我已经看到了有关如何设置ModelMultipleChoiceField以使用自定义查询集的所有howtos,并且我尝试了它们,并且它们都可以正常工作。但是,它们都使用相同的范例:查询集只是相同对象的过滤列表。将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' 

我想,这将是容易的,但它变成死角小时。任何人都在关注一些光明?

回答

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,但你可以试试。

+0

为什么我被低估了?你可以解释吗 ? – sebpiq 2010-05-17 09:14:56

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

+0

我会这样做,除了在这种情况下,有问题的模型是用户,我不控制。你知道我将如何调整User类的__unicode__属性吗? – 2010-05-17 06:40:46

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=参数,一切工作。感谢大家!