2010-06-06 4 views
4

Хорошо, я просматривал документацию Google и Django уже более 2 часов (а также канал IRC на freenode) и не смог понять это.Как заполнить данные формы по умолчанию с помощью поля ManyToMany?

В принципе, у меня есть модель под названием 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.

В принципе, если админы нажимают на объект Room для редактирования, на странице, на которую они идут, будут отображаться все значения по умолчанию , за исключением «запретов». Независимо от того, что я делаю, я не могу найти способ заставить 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! 

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

Спасибо!

UPDATE

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

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()] 

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

+0

Если редактор комнаты может редактировать только одно поле, только дать их поля taht для редактирования и отображения остальной части данных комнаты в виде текста дисплея. Это также обойдутся вашей проблемой, инициализируя поля по умолчанию M2M –

+0

, что вы имеете в виду, если «это не работает должным образом»? это порождение или ничего? –

ответ

0

Вы, вероятно, нужно использовать «первоначальный»:. Django set default form values

+0

«initial» - это то же самое, что и «default», они оба работают. Как я уже сказал выше, код в настоящее время правильно устанавливает все значения по умолчанию для EXCEPT для поля «запреты» (которое является ManyToMany). Этот вопрос касается кода, необходимого для установки значения формы по умолчанию для поля ManyToMany. – rdegges

+1

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

+0

Спасибо, это сработало.Передача в списке первичных ключей была именно тем, что мне нужно было сделать. Тьфу! Я собираюсь обновить вопрос с помощью решения. – rdegges

Смежные вопросы