2010-06-06 110 views
4

好的,我一直在爬行谷歌和Django文档超过2个小时(以及freenode上的IRC频道),并没有能够找出这一个。如何使用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) 

我也得到了它具有以下的ModelForm代表我Room模型forms.py:

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,他们所去的页面将显示除'禁止'之外的所有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()] 

和BAM,它会立即开始工作(当我查看的页面,它会显示的Caller个可选列表,与已经禁止来电者已经强调(选择)

+0

如果房间的编辑器只能编辑一个字段,只给他们在字段中编辑并将房间的其余数据显示为显示文本。这也将解决初始化M2M的缺省字段的问题 – 2010-06-06 09:22:32

+0

你的意思是“它无法正常工作”?它产生了一个或是没有任何东西? – 2010-06-06 15:23:11

回答

0

您可能需要使用“初始”:Django set default form values

+0

'initial'与'default'是一样的,它们都起作用。正如我上面所说,代码当前正确设置所有默认值,除了'禁止'字段(这是一个ManyToMany)。此问题涉及为ManyToMany字段设置默认表单值所需的代码。 – rdegges 2010-06-06 16:56:12

+1

以及我现在不能真正验证,但我认为我做了一次,我不得不将对象主键传递给它,而不是一个查询集... – 2010-06-06 17:10:26

+0

谢谢,这工作。传递主键列表正是我需要做的。啊!我将用解决方案更新问题。 – rdegges 2010-06-06 18:50:02

相关问题