Хорошо, я сканирую документацию 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
с, когда уже заблокированные абоненты уже выделены (выбраны).