我正在使用q& a at Get Primary Key after Saving a ModelForm in Django
这正是我需要做的事情。
我有以下型号:
class meetingEvent(models.Model):
'''
A meeting event
'''
name = models.CharField(max_length=64, help_text="a name for this meeting")
account_number = models.ForeignKey(account)
meeting_type = models.ForeignKey(meetingType)
meeting_group = models.ForeignKey(meetingGroup)
start_time = models.DateTimeField(help_text="start time for this event")
end_time = models.DateTimeField(help_text="end time for this event")
created_time = models.DateTimeField(auto_now_add=True)
listed_products = models.ForeignKey(product)
additonal_notes = models.TextField(help_text="additional notes for this meeting")
def __unicode__(self):
return self.name
我有以下表格:
class meetingEventForm(forms.ModelForm):
"""
to create a new meeting event.
"""
portal_user = forms.CharField(help_text="username to access portal data")
portal_pass = forms.CharField(widget=forms.PasswordInput, help_text="password to add access portal data")
def save(self, commit=True):
super(meetingEventForm, self).save(commit=commit)
class Meta:
model = meetingEvent
我有以下观点:
def meeting_event(request):
if request.method == 'POST':
form = meetingEventForm(request.POST)
if form.is_valid():
new_agenda=form.save()
return HttpResponseRedirect(reverse('agenda_detail', args=(new_agenda.pk,)))
else:
form = meetingEventForm()
return render_to_response('agendas/event.html',{'form':form,}, context_instance=RequestContext(request))
我已经确认这会让它干净利落地进入数据库。 但是,我收到以下错误:
Traceback:
File "/usr/lib/python2.6/site-packages/Django-1.5.2-py2.6.egg/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.6/site-packages/Django-1.5.2-py2.6.egg/django/contrib/auth/decorators.py" in _wrapped_view
25. return view_func(request, *args, **kwargs)
File "/var/www/html/tamtools/agendas/views.py" in meeting_event
44. return HttpResponseRedirect(reverse('agenda_detail', args=(new_agenda.pk,)))
Exception Type: AttributeError at /agendas/add/
Exception Value: 'NoneType' object has no attribute 'pk'
我不知道Django 1.5中有什么变化吗? new_agenda应该是一个meetingEventForm类型,不应该吗?
答案 0 :(得分:2)
您在模型中覆盖了save方法,但忘记返回模型。
return super( ....
答案 1 :(得分:1)
您不需要覆盖ModeForm保存方法,因为您没有对它执行任何特殊操作。您的ModelForm应如下所示:
class MeetingEventForm(forms.ModelForm):
"""
to create a new meeting event.
"""
class Meta:
model = meetingEvent
我还更改了类名以符合Python style guide。
表单中还有两个与模型无关的额外字段。可能有两个原因 - 一个是您需要将这些字段保存在另一个模型中,或者第二个选项是您希望有人在添加新事件之前自行授权。
由于第二个似乎更合理,因此从您的视图中限制对表单的访问:
from django.contrib.auth.decorators import login_required
from django.shorcuts import render, redirect
@login_required()
def meeting_event(request):
form = MeetingEventForm(request.POST or {})
context = {'form': form}
if request.method == 'POST':
if form.is_valid():
new_agenda = form.save()
return redirect('agenda_detail', args=(new_agenda.pk,))
else:
return render(request, 'agendas/event.html', context)
else:
return render(request, 'agendas/event.html', context)
由于这是一项常见任务,并且您使用的是django 1.5,为什么不使用通用class based views?
您的代码将会减少,您不必担心平凡的细节:
首先,在views.py
中,创建一个继承自通用CreateView
的类,用于显示模型的模型表单,让用户填写它,并保存详细信息:
from django.views.generic.edit import CreateView
class CreateMeetingRequest(CreateView):
template_name = 'agendas/event.html'
model = meetingRequest
现在,要将视图映射到网址,我们将其添加到urls.py
。由于我们还希望用户在添加会议请求之前登录 - login_required
装饰器会为我们处理。它将检查用户是否已登录 - 如果没有,则将用户重定向到登录表单,一旦他们登录,将其重定向回表单:
from django.contrib.auth.decorators import login_required
from .views import CreateMeetingRequest
urlpatterns = patterns('',
# your other views
url(r'meeting-request/add/$',
login_required(CreateMeetingRequest.as_view()), name='add-meeting-req'),
)
最后,我们需要在表单成功后告诉视图去哪里。 CreateView
会检查模型是否有get_absolute_url
方法,然后调用它。所以在models.py
:
from django.core.urlresolvers import reverse
class meetingRequest(models.Model):
# your normal fields
def get_absolute_url(self):
return reverse('agenda_detail', args=(self.pk,))