Django初始为ManyToMany字段

Den*_*oko 1 django django-forms

我有一个表单可以编辑我的模型实例.我想使用表单将所有隐藏的值传递username给已登录用户的默认值,以便它成为一个subscribe表单.问题是,正常initial={'field':value}情况似乎不适用于许多领域.我该怎么办呢?

我的views.py

@login_required
def event_view(request,eventID):
    user = UserProfile.objects.get(pk=request.session['_auth_user_id'])
    event = events.objects.get(eventID = eventID)
    if request.method == 'POST':
        form = eventsSusbcribeForm( request.POST,instance=event)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/events/')

    else:
        form = eventsSusbcribeForm(instance=event)

    return render_to_response('event_view.html', {'user':user,'event':event, 'form':form},context_instance = RequestContext( request ))
Run Code Online (Sandbox Code Playgroud)

我的forms.py

class eventsSusbcribeForm(forms.ModelForm):
    eventposter = forms.ModelChoiceField(queryset=UserProfile.objects.all(), widget=forms.HiddenInput())
    details = forms.CharField(widget=forms.Textarea(attrs={'cols':'50', 'rows':'5'}),label='Enter Event Description here')
    date = forms.DateField(widget=SelectDateWidget())


    class Meta:
        model = events
        exclude = ('deleted')

    def __init__(self, *args, **kwargs):
        super(eventsSusbcribeForm, self).__init__(*args, **kwargs)
        self.fields['username'].initial = (user.id for user in UserProfile.objects.filter())
Run Code Online (Sandbox Code Playgroud)

我的models.py

class events(models.Model):
    eventName  = models.CharField(max_length=100)
    eventID =  models.AutoField(primary_key=True)
    details = models.TextField()
    attendanceFee = models.FloatField(max_length=99)
    date = models.DateField()
    username = models.ManyToManyField(UserProfile, related_name='user', blank=True)
    eventposter = models.ForeignKey(UserProfile, related_name='event_poster')
    deleted = models.BooleanField()

    def __unicode__(self):
        return u'%s' % (self.eventName)
Run Code Online (Sandbox Code Playgroud)

Cas*_*ark 8

你可以发布你的活动模型吗?如果没有它,你很难猜到你想要做什么.没有它,我必须承担一些事情,所以如果我错了,我很抱歉.

首先,我猜你不应该为EventSubscriptionForm使用Event ModelForm.这没有多大意义.希望你为Event和User创建了一个直通类,所以在你的Event模型中,你有类似的东西

subscriber_users = models.ManyToManyField(User, through="Subscription")
Run Code Online (Sandbox Code Playgroud)

class Subscription(models.Model):
    user = models.ForeignKey(User, related_name="events",)
    event = models.ForeignKey(Event, related_name="subscribers")
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用Subscription ModelForm.

你有没有理由使用eventID而不是django idiom,event_id?您还应该使用Pythonic外壳导入Event和EventSubcribeForm类.一个非常重要的事情是你应该将所有内容链接到User而不是UserProfile.

从技术上讲,在视图中设置initial比在init中更有意义,因为无论如何你都必须将request.user传递给init.

我想你应该试试这个......

@login_required
def event_view(request, event_id=None):
    user = request.user.get_profile()
    event = Event.objects.get(id=event_id)
    initial = {'user': request.user}

    form = EventSubcriptionForm(request.POST or None, instance=event, initial=initial)
    if form.is_valid():
        form.save()
        return HttpResponseRedirect(reverse('event_list'))

    return render_to_response('event_view.html', {
        'event': event,
        'form': form
    }, context_instance = RequestContext(request))
Run Code Online (Sandbox Code Playgroud)

几点说明

  • 对当前用户的配置文件对象使用request.user.get_profile()
  • 您可以使用request.POST or None以避免request.method案例
  • 始终使用命名网址,以便您可以反转名称而不是将网址硬编码到视图中
  • 如果您想user在模板上下文中,只需设置上下文处理器(请参阅pinax,例如关于如何执行此操作),而不是在每个视图中传递它.您也可以始终使用request.user.

请记住,只有通过我所说的类设置并使用类似的表格时,此代码才有效

class EventSubcriptionForm(forms.ModelForm):
    class Meta:
        model = Subscription
        exclude = ('event')
Run Code Online (Sandbox Code Playgroud)

编辑 感谢一堆人.我不是django的新手,但不知何故对SO来说很新.

好的,你应该真正阅读一些关于Python约定的PEP http://www.python.org/dev/peps/pep-0008/或者关于它的一些SO帖子Python中变量和函数名称的命名约定是什么?.

以下是我为您的活动应用程序models.py推荐的内容:

class Event(models.Model):
    name  = models.CharField(max_length=100)
    details = models.TextField()
    attendance_fee = models.FloatField(max_length=99)
    date = models.DateField()
    poster = models.ForeignKey(User, related_name='events_posted')
    deleted = models.BooleanField()

    attendee_users = models.ManyToManyField(User, through="Attendance")

    def __unicode__(self):
        return self.name

class Attendance(models.Model):
    user = models.ForeignKey(User, related_name="events",)
    event = models.ForeignKey(Event, related_name="attendees")
Run Code Online (Sandbox Code Playgroud)

笔记

  • 类的名称是大写的和单数的.您没有描述事件,您是活动的蓝图.
  • 你永远不需要在其属性中使用类的名称,即event_name可以只是名称.
  • 所有变量都是lowercase_and_underscored
  • 始终链接到用户,而不是您的个人资料模型.很多django代码都希望如此.

现在,您可以使用event.attendees访问参加活动的用户.