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

发布于 2024-09-01 23:25:07 字数 1390 浏览 5 评论 0原文

我已经看过所有有关如何设置 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'

我认为这很容易,但它变成了几个小时的死胡同。有人愿意透露一些信息吗?

I've seen all the howtos about how you can set a ModelMultipleChoiceField to use a custom queryset and I've tried them and they work. However, they all use the same paradigm: the queryset is just a filtered list of the same objects.

In my case, I'm trying to get the admin to draw a multiselect form that instead of using usernames as the text portion of the , I'd like to use the name field from my account class.

Here's a breakdown of what I've got:

# 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

This works, however, I want queryset above to draw a selectbox with the Account.name property and the User.id property. This didn't work:

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

It failed with this error:

'tuple' object has no attribute 'pk'

I figured that this would be easy, but it's turned into hours of dead-ends. Anyone care to shed some light?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九厘米的零° 2024-09-08 23:25:07

您可以使用自定义小部件,覆盖其 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,但你可以尝试一下。

You can use a custom widget, override its render method. Here's what I had done for a text field :

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)        

Then of course, use the widget parameter of your administrator field, in order to use your custom widget.
I don't know if it can be adapted for a select, but you can try out.

逆流 2024-09-08 23:25:07

查询集必须是一个查询集,当你执行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 即可。

The queryset needs to be a QuerySet, when you do values_list you get a list so that won't work.

If you want to change the default display of models, just override __unicode__. See http://docs.djangoproject.com/en/dev/ref/models/instances/#unicode

For example:

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

Django will use __unicode__ whenever you asks it to print a model. For testing you can just load up a model in the shell and do print my_instance.

凉宸 2024-09-08 23:25:07

从 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= 参数,一切就正常了。谢谢大家!

Taking a queue from sebpiq, I managed to figure it out:

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)

The key was abandoning the queryset altogether. Once I went with a fixed choices= parameter, everything just worked. Thanks everyone!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文