【问题标题】:Django set creator/owner for the object when createdDjango 在创建时为对象设置创建者/所有者
【发布时间】:2014-04-04 18:46:46
【问题描述】:

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

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找到了解决方案

【问题讨论】:

  • 产生错误的代码在哪里?
  • @m5seppal 显示保存模型的视图代码
  • 我忘了说我正在使用基于类的视图,我编辑了问题
  • 当我将视图更改为使用 django 的通用 CreateView 而不是 CreateWithInlinesView 时,我设法完成了这项工作。我发布了一个关于该问题的新question。谢谢你们的帮助!

标签: django django-models auto-populate


【解决方案1】:

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

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

如果您在视图中,并使用ModelForm 创建Contact,请传递commit=False kwarg 以保存方法(如您发布的链接中的示例)。这将阻止创建联系人,直到您分配 owner = request.user。

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

【讨论】:

  • 这正是我尝试过的,但我仍然得到那个错误:“owner_id”列中的空值违反了非空约束看起来 form_valid 从未被调用。你知道我应该怎么做吗?
  • @well 还要确保该请求有一个用户。您可以使用 @login_required 装饰器来做到这一点。我假设用户没有登录这就是为什么request.user 是None
  • 我正在使用 LoginRequiredMixin,它应该做同样的事情。它来自 django-braces。
【解决方案2】:

假设你使用的是ContactFormModelForm:

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

【讨论】:

  • 什么也没发生。
【解决方案3】:

问题是form_valid方法的默认实现设置self.object,然后get_success_url使用它来确定重定向到哪里。

如果你用self.object替换你本地的obj变量,你应该没问题:

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 上快速检查了原始实现的副作用,这对于发现我需要在子类实现中重现的任何副作用很有用。

【讨论】:

  • 什么都没发生。
猜你喜欢
  • 1970-01-01
  • 2019-01-17
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 2013-05-26
  • 1970-01-01
相关资源
最近更新 更多