动态表单生成

2 投票
1 回答
615 浏览
提问于 2025-04-16 19:23

我有一个关于活动邀请的模型:

class EventInvitation(models.Model):

    from_user = models.ForeignKey(User, related_name="inviters")
    to_user = models.ForeignKey(User, related_name="invited")
    text = models.CharField(max_length= 150)
    event = models.ForeignKey(Event)
    sent = models.DateTimeField(auto_now=True)
    status = models.IntegerField(choices=INVITATION_STATI, default=0)

我想做的是一个动态的邀请表单(不是模型表单),在这个表单中,发起邀请的人可以根据查询选择用户,这些用户是可以被这个特定用户邀请的。同时,还可以选择一些小组,这些小组也是根据查询得出的(发起邀请的人必须是小组的拥有者)。因为这个活动邀请是针对单个用户的,所以我会遍历选中的用户和小组的成员,为他们每个人创建单独的邀请。你觉得我该怎么生成这个动态表单呢?

1 个回答

3

根据我的理解,你想要的是一个已经登录的用户,在活动页面上点击一个“邀请其他人”的按钮,这样就会弹出一个表单,用户可以在里面选择特定的用户和群组,填写一些文字,然后点击“发送”。接着,你的应用程序应该为每个用户创建一个邀请实例,并发送这些邀请,同时跟踪邀请的状态。如果我的理解没错,下面是我对实现这个功能的一些建议:

使用以下模型可以让你更好地管理数据(只保存一次文本,并且可以查找特定邀请的所有用户):

class EventInvitation(models.Model):
    inviter = models.ForeignKey(User, related_name="inviters")
    event = models.ForeignKey(Event)
    text = models.CharField(max_length= 150)
    created = models.DateTimeField(auto_now=True)

class EventInvitationInvitee(models.Model):
    event_invitation = models.ForeignKey(EventInvitation)
    user = models.ForeignKey(User, related_name="invited")
    status = models.IntegerField(choices=INVITATION_STATI, default=0)

可以使用一个简单的表单,像这样:

from django.contrib.auth.models import User, Group

class InviteForm(forms.Form):
    text = forms.CharField(widget=forms.Textarea)
    users = forms.ModelMultipleChoiceField(queryset=User.objects.all())
    groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all())

    def __init__(self, user, *args, **kwargs):
      super(InviteForm, self).__init__(*args, **kwargs)
      self.fields['users'].queryset = User.objects.filter( ... )
      self.fields['groups'].queryset = User.objects.filter( ... )

...替换成你用来筛选正确的群组和用户的代码。

然后用这种方式来展示视图:

def invite(request, event_id):
    event = get_object_or_404(Event, pk=event_id) # you can check if your user is allowed to access this event here
    if request.method == 'POST':
        form = InviteForm(request.user, request.POST)
        if form.is_valid():
            invitation = EventInvitation.objects.create(inviter=request.user, event=event,  text = form.cleaned_data['text'])
            users = set()
            for user in form.cleaned_data['users']:
                users.add(user)
                EventInvitationInvitee.objects.create(event_invitation=invitation, user=user)
            for group in form.cleaned_data['groups']:
                for user in group.user_set.all():
                    if user not in users:
                        users.add(user)
                        EventInvitationInvitee.objects.create(event_invitation=invitation, user=user)
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = InviteForm(request.user)

    return render_to_response('invite.html', {'form': form})

更新: 你也可以用更符合Python风格的方式创建一个动态表单,像这样:

def get_invite_form(user):

  class InviteForm(forms.Form):
      text = forms.CharField(widget=forms.Textarea)
      users = forms.ModelMultipleChoiceField(queryset= ... )
      groups = forms.ModelMultipleChoiceField(queryset= ... )

  return InviteForm

...替换成使用用户参数的查询集,然后后面用get_invite_form(request.user)(request.POST)get_invite_form(request.user)()来代替InviteForm()

撰写回答