Динамическая установка набора запросов ModelMultipleChoiceField в пользовательский набор записей - PullRequest
1 голос
/ 17 мая 2010

Я видел все инструкции о том, как вы можете установить 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'

Я подумал, что это будет легко, но это превратилось в часы тупиков. Кто-нибудь хочет пролить свет?

Ответы [ 3 ]

1 голос
/ 17 мая 2010

Вы можете использовать пользовательский виджет, переопределить его 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 голосов
/ 17 мая 2010

Взяв очередь из 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=, все просто заработало. Спасибо всем!

0 голосов
/ 17 мая 2010

Набор запросов должен быть 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__ всякий раз, когда вы просите его напечатать модель. Для тестирования вы можете просто загрузить модель в оболочку и сделать print my_instance.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...