假设我有一个简单的模型:
class Contact(models.Model):
owner = models.ForeignKey(User, editable=False)
first_name = models.CharField(max_length=255,)
last_name = models.CharField(max_length=255,)
email = models.EmailField()
我想在创建对象时自动为对象设置所有者(request.user,登录用户)。我已经搜索了很多不同的选项,但其中大多数都与您在管理方面的工作方式有关,而其他选项对我不起作用。例如,我尝试了这个 http://blog.jvc26.org/2011/07/09/django-automatically-populate-request-user 然后我尝试了很多方法来覆盖保存方法或某种pre_save信号的东西。似乎没有什么可以解决问题,我只是得到一个错误
IntegrityError at /new
null value in column "owner_id" violates not-null constraint
正确的方法是什么?我知道这很简单,但我就是找不到方法。
。编辑。。。我的创建视图如下所示:
class CreateContactView(LoginRequiredMixin, ContactOwnerMixin, CreateWithInlinesView):
model = models.Contact
template_name = 'contacts/edit_contact.html'
form_class = forms.ContactForm
inlines = [forms.ContactAddressFormSet]
def form_valid(self, form):
obj = form.save(commit=False)
obj.owner = self.request.user
obj.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('contacts-list')
def get_context_data(self, **kwargs):
context = super(CreateContactView, self).get_context_data(**kwargs)
context['action'] = reverse('contacts-new')
return context
到目前为止,这只是我试图解决这个问题的一种方式。我从 http://blog.jvc26.org/2011/07/09/django-automatically-populate-request-user 中找到了该解决方案
假设您使用的是ContactForm
ModelForm
:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
contact = form.save(commit=False)
contact.owner = request.user
contact.save()
return HttpResponseRedirect('/thanks/')
else:
# do stuff
请发布您尝试过的确切代码。
如果您的视图要求用户登录,请确保强制执行。 这可以通过使用@login_required
装饰器来完成
如果您在视图中,并使用ModelForm
创建Contact
,请传递commit=False
kwarg to save 方法(如您发布的链接中的示例)。 这将阻止创建联系人,直到您分配owner = request.user
。
由于登录用户仅在请求上下文中可用,因此只需确保在创建新Contact
时设置owner
将其归因于视图
问题是 form_valid
方法的默认实现设置 self.object
,然后get_success_url
使用它来确定重定向到的位置。
如果将局部obj
变量替换为 self.object
,您应该没问题:
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.owner = self.request.user
self.object.save()
return HttpResponseRedirect(self.get_success_url())
我发现在 Classy Class-Based Views 网站上快速检查原始实现的副作用,或者 GitHub 上的 Django 源代码,对于发现我需要在子类实现中重现的任何副作用很有用。