Django 在创建时为对象设置创建者/所有者



假设我有一个简单的模型:

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 源代码,对于发现我需要在子类实现中重现的任何副作用很有用。