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

时间:2014-03-03 16:06:52

标签: django django-models auto-populate

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

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

找到了解决方案

3 个答案:

答案 0 :(得分:3)

假设您使用的是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

答案 1 :(得分:0)

请发布您尝试过的确切代码。

如果您的视图要求用户已登录,请确保其已强制执行。这可以通过使用@login_required装饰器

来完成

如果您在视图中,并使用ModelForm创建Contact,请将commit=False kwarg传递给save方法(例如您发布的链接中的示例)。这将在您分配owner = request.user

之前保持联系人的创建

由于登录用户仅在请求的上下文中可用,因此请确保在创建新owner时将Contact属性视为属性

答案 2 :(得分:0)

问题是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网站上副作用的原始实现的快速检查,或Django source-code on GitHub有助于发现我需要在子类实现中重现的任何副作用。