Хорошо, я просматривал документацию 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
с, с уже запретили звонящие уже выделен (выбран)
Если редактор комнаты может редактировать только одно поле, только дать их поля taht для редактирования и отображения остальной части данных комнаты в виде текста дисплея. Это также обойдутся вашей проблемой, инициализируя поля по умолчанию M2M –
, что вы имеете в виду, если «это не работает должным образом»? это порождение или ничего? –