Как заполнить данные формы по умолчанию полем ManyToMany? - PullRequest
5 голосов
/ 06 июня 2010

Хорошо, я сканирую документацию google и Django уже более 2 часов (а также канал IRC на freenode) и не смог выяснить это.

По сути, у меня есть модель с именем Room, которая отображается ниже:

class Room(models.Model):
    """
    A `Partyline` room. Rooms on the `Partyline`s are like mini-chatrooms. Each
    room has a variable amount of `Caller`s, and usually a moderator of some
    sort. Each `Partyline` has many rooms, and it is common for `Caller`s to
    join multiple rooms over the duration of their call.
    """
    LIVE = 0
    PRIVATE = 1
    ONE_ON_ONE = 2
    UNCENSORED = 3
    BULLETIN_BOARD = 4
    CHILL = 5
    PHONE_BOOTH = 6
    TYPE_CHOICES = (
        ('LR', 'Live Room'),
        ('PR', 'Private Room'),
        ('UR', 'Uncensored Room'),
    )

    type = models.CharField('Room Type', max_length=2, choices=TYPE_CHOICES)
    number = models.IntegerField('Room Number')
    partyline = models.ForeignKey(Partyline)
    owner = models.ForeignKey(User, blank=True, null=True)
    bans = models.ManyToManyField(Caller, blank=True, null=True)

    def __unicode__(self):
        return "%s - %s %d" % (self.partyline.name, self.type, self.number)

У меня также есть файл forms.py со следующей ModelForm для представления моей Room модели:

from django.forms import ModelForm

from partyline_portal.rooms.models import Room


class RoomForm(ModelForm):
    class Meta:
        model = Room

Я создаю представление, которое позволяет администраторам редактировать данный Room объект. Вот мой взгляд (пока):

def edit_room(request, id=None):
    """
    Edit various attributes of a specific `Room`. Room owners do not have
    access to this page. They cannot edit the attributes of the `Room`(s) that
    they control.
    """
    room = get_object_or_404(Room, id=id)
    if not room.is_owner(request.user):
        return HttpResponseForbidden('Forbidden.')

    if is_user_type(request.user, ['admin']):
        form_type = RoomForm
    elif is_user_type(request.user, ['lm']):
        form_type = LineManagerEditRoomForm
    elif is_user_type(request.user, ['lo']):
        form_type = LineOwnerEditRoomForm

    if request.method == 'POST':
        form = form_type(request.POST, instance=room)
        if form.is_valid():
            if 'owner' in form.cleaned_data:
                room.owner = form.cleaned_data['owner']

        room.save()
    else:
        defaults = {'type': room.type, 'number': room.number, 'partyline': room.partyline.id}
        if room.owner:
            defaults['owner'] = room.owner.id
        if room.bans:
            defaults['bans'] = room.bans.all() ### this does not work properly!

        form = form_type(defaults, instance=room)

    variables = RequestContext(request, {'form': form, 'room': room})
    return render_to_response('portal/rooms/edit.html', variables)

Теперь этот вид работает нормально, когда я просматриваю страницу. Он показывает все атрибуты формы, и все значения по умолчанию заполнены (когда пользователи делают GET) ... КРОМЕ для значений по умолчанию для поля ManyToMany 'bans'.

По сути, если администратор нажимает на объект Room для редактирования, на странице, на которую они переходят, будут показаны все значения по умолчанию Room s, кроме «запретов». Независимо от того, что я делаю, я не могу найти способ заставить Django отображать «заблокированных пользователей» для объекта Room. Вот строка кода, которую нужно изменить (из вида):

defaults = {'type': room.type, 'number': room.number, 'partyline': room.partyline.id}
if room.owner:
        defaults['owner'] = room.owner.id
if room.bans:
        defaults['bans'] = room.bans.all() ### this does not work properly!

Должен быть какой-то другой синтаксис, который я должен использовать, чтобы указать значение по умолчанию для поля 'bans'. Я действительно выдернул свои волосы на этом, и определенно был бы благодарен за некоторую помощь.

Спасибо!

UPDATE

Лазерная наука фактически помогла мне найти решение в одном из его комментариев. По сути, это работает, если вы передаете список первичных ключей. Чтобы это работало, мне пришлось изменить:

if room.bans:
        defaults['bans'] = room.bans.all() ### this does not work properly!

до

if room.bans:
        defaults['bans'] = [b.pk for b in room.bans.all()]

И bam, он мгновенно начал работать (когда я просматриваю страницу, он показывает список на выбор Caller с, когда уже заблокированные абоненты уже выделены (выбраны).

1 Ответ

0 голосов
/ 06 июня 2010

Возможно, вам нужно использовать «начальный»: Django установить значения формы по умолчанию

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