使用django中的通用create_object视图设置对象所有者

时间:2009-03-12 18:02:08

标签: python django

是否可以使用create_object视图创建新对象并自动将request.user作为外键?

体育课:

class Post(models.Model):
    text = models.TextField()
    author = models.ForeignKey(User)

我想要的是使用create_object并使用request.user填充作者。

5 个答案:

答案 0 :(得分:3)

您可能需要考虑关闭。

from django.forms import ModelForm
from django.views.generic.create_update import create_object, update_object

def make_foo_form(request):
    class FooForm(ModelForm):
        class Meta:
            model = Foo
            fields = ['foo', 'bar']

        def save(self, commit=True):
            f = super(FooForm, self).save(commit=False)
            if not f.pk: f.user = request.user
            if commit: f.save()
            return f

    return FooForm

def create_foo(request):
    FooForm = make_foo_form(request)
    return create_object(form_class=FooForm)

这里有一些低效率,因为您需要在每个请求上创建ModelForm对象,但它确实允许您将功能注入到通用视图中。

您需要确定表单创建的额外复杂性是否值得在视图方面保持简洁性。

然而,这里的一个好处是,这也适用于更新案例,几乎不需要额外的努力:

def update_foo(request, object_id):
    FooForm = make_foo_form(request)
    return update_object(form_class=FooForm, object_id=object_id)

显然,您也可以将此方法用于更复杂的案例。

答案 1 :(得分:2)

在许多方面,所有解决方案都会比它们的价值更麻烦。这个有资格作为黑客。如果更改create_update的实现方式,django更新可能会让您高度干燥。为简单起见,我假设您正在尝试设置默认用户,而不是以静默方式强制用户成为登录用户。

编写上下文处理器:

from django.views.generic.create_update import get_model_and_form_class
def form_user_default(request):
    if request.method == 'GET':
        model, custom_form = get_model_and_form_class(Post,None)
        custom_form.author = request.user
        return {'form':custom_form}
    else: return {}

这样做会覆盖create_update传递给模板的表单对象。它在技术上做的是在默认视图完成后重新创建表单。

然后在你的网址中:

url(r'pattern_to_match', 'django.views.generic.create_update.create_object', kwargs={'context_processors':form_user_default})

同样,我不得不深入研究源代码以找出如何做到这一点。尝试编写自己的视图(但尽可能多地包含Django自定义对象)可能真的是最好的。没有“简单的默认”方法,因为在django范式中,模型与模型层的关系比与视图的关系更紧密,只有视图才能了解请求对象。

答案 2 :(得分:1)

如果用户已通过身份验证,则其用户对象为request.user对象。

我不熟悉create_object ...我仍然是django的初学者,并且刚开始我的第一个真正的项目。

请注意,在使用之前,应检查以确保用户已登录。这可以使用request.user.is_authenticated()完成。

答案 3 :(得分:0)

使用当前的Django通用视图时,没有好的方法可以挂钩保存对象。一旦它们为rewritten as classes,您就可以将视图子类化并在适当的位置挂钩,而无需重写整个视图。

出于这个原因,我已经使用了自己的基于类的通用视图。

答案 4 :(得分:0)

我建议为create_object创建一个包装器,正如本作者所建议的那样 http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/ 在视图中,您将可以访问用户信息。 之后,您将需要使用extra_context将用户传递给模板。最后,在模板中,您可以添加带有用户信息的隐藏字段。我没有尝试过,但我已经考虑了很长一段时间了。希望这个解决方案适合你! ;)干杯!