我如何使用ManyToMany字段填充默认表单数据?

8 浏览
0 Comments

我如何使用ManyToMany字段填充默认表单数据?

好的,我已经在谷歌和Django文档上爬行了两个多小时(以及freenode上的IRC频道),但是还没有找到答案。\n基本上,我有一个名为Room的模型,如下所示:\n

class Room(models.Model):
    """
    一个`Partyline`的房间。`Partyline`上的房间就像迷你聊天室。每个房间有不同数量的`Caller`,通常有一个调解员。每个`Partyline`有很多房间,`Caller`在通话的过程中通常会加入多个房间。
    """
    LIVE = 0
    PRIVATE = 1
    ONE_ON_ONE = 2
    UNCENSORED = 3
    BULLETIN_BOARD = 4
    CHILL = 5
    PHONE_BOOTH = 6
    TYPE_CHOICES = (
        ('LR', '实时房间'),
        ('PR', '私人房间'),
        ('UR', '无审查房间'),
    )
    type = models.CharField('房间类型', max_length=2, choices=TYPE_CHOICES)
    number = models.IntegerField('房间号')
    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)

\n我还有一个forms.py,其中有以下ModelForm来表示我的Room模型:\n

from django.forms import ModelForm
from partyline_portal.rooms.models import Room
class RoomForm(ModelForm):
    class Meta:
        model = Room

\n我正在创建一个视图,允许管理员编辑给定的Room对象。这是我的视图(到目前为止):\n

def edit_room(request, id=None):
    """
    编辑特定的`Room`的各种属性。房主无法访问此页面。他们不能编辑他们控制的`Room`的属性。
    """
    room = get_object_or_404(Room, id=id)
    if not room.is_owner(request.user):
        return HttpResponseForbidden('禁止访问。')
    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() ### 这个无法正常工作!
        form = form_type(defaults, instance=room)
    variables = RequestContext(request, {'form': form, 'room': room})
    return render_to_response('portal/rooms/edit.html', variables)

\n现在,当我查看页面时,这个视图工作得很好。它显示了所有表单属性,并填充了所有的默认值(当用户进行GET操作时)...除了ManyToMany字段“bans”的默认值。\n基本上,如果管理员点击一个要编辑的Room对象,他们进入的页面将显示Room的所有默认值,除了“bans”。无论我做什么,我都找不到一种方法让Django显示当前Room对象的“banned users”的方式。这是需要更改的代码行(来自视图):\n

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() ### 这个无法正常工作!

\n肯定还有其他语法我必须使用来指定“bans”字段的默认值。我真的在这个问题上绞尽脑汁,非常感谢你的帮助。\n谢谢!\n更新\nlazerscience实际上在他的评论中帮助我找到了解决方案。基本上,它的工作原理是如果传递一个主键列表。为了使它工作,我必须更改:\n

if room.bans:
        defaults['bans'] = room.bans.all() ### 这个无法正常工作!

\n为\n

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

\n然后,它立即开始工作(当我查看页面时,它将显示一个可选择的Caller列表,已经被禁止的Caller已经被突出显示(选中)。

0
0 Comments

问题出现的原因是需要在一个带有ManyToMany字段的表单中设置默认的表单数据。目前的代码可以正确设置除了'bans'字段(ManyToMany字段)之外的所有默认值。解决方法是将对象的主键传递给该字段,而不是传递一个queryset。

0