【问题标题】:How to subclass django's generic CreateView with initial data?如何使用初始数据对 django 的通用 CreateView 进行子类化?
【发布时间】:2011-08-05 16:59:43
【问题描述】:

我正在尝试创建一个对话框,该对话框使用 jquery 的 .load() 函数以呈现的 django 形式啜饮。 .load 函数传递了“alert”对象的 pk。在类函数中还可以使用self.request.user 之类的东西,因此我可以预先填写这些字段,如下所示的消息模型 (models.py):

class Message(models.Model):

    user = models.ForeignKey(User)
    alert = models.ForeignKey(Alert)
    date = models.DateTimeField()
    message = models.TextField()

子类化 django 的 CreateView 可以很容易地使用 ModelForm (views.py) 的实例生成上下文:

class MessageDialogView(CreateView):
    """ show html form fragment """
    model = Message
    template_name = "message.html"

    def get_initial(self):
        super(MessageDialogView, self).get_initial()
        alert = Alert.objects.get(pk=self.request.POST.get("alert_id"))
        user = self.request.user
        self.initial = {"alert":alert.id, "user":user.id, "message":"test"}
        return self.initial


    def post(self, request, *args, **kwargs):
        super(MessageDialogView, self).post(request, *args, **kwargs)
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        context = self.get_context_data(form=form)
        return self.render_to_response(context)

这里的问题是self.initial 没有与表单一起呈现。我已经确保表单确实在调用get_initial,并且表单实例在post 中具有正确的初始数据,但是当表单在模板message.html 中呈现时,它不会像我一样抓取任何初始数据会期望。有什么特别的技巧可以让它工作吗?我已经搜索了文档(似乎缺少基于泛型的类视图的示例)和源代码,但我看不出我缺少什么。

【问题讨论】:

    标签: django-forms django-views django-class-based-views


    【解决方案1】:

    get_initial() 应该只返回一个字典,而不是设置self.initial

    你的方法应该是这样的:

    def get_initial(self):
        # Get the initial dictionary from the superclass method
        initial = super(YourView, self).get_initial()
        # Copy the dictionary so we don't accidentally change a mutable dict
        initial = initial.copy()
        initial['user'] = self.request.user.pk
           # etc...
        return initial
    

    【讨论】:

    • 请原谅我的无知,但不复制字典有什么风险?
    • @HarryGordon 试试这个:dict1 = {'a':1,'b':2} dict2 = dict1 dict2['b']=10 print(dict1)
    • 看起来所有的换行符都丢失了:(
    • 谢谢 Zhe,但我不明白为什么副本在这种特殊情况下很重要 - 只有当对象仍在其他地方使用时才重要...?
    • @HarryGordon 因为是这样定义的in the source.
    【解决方案2】:

    你可以像这样使用:

    from django.shortcuts import HttpResponseRedirect
    
        class PostCreateView(CreateView):
            model = Post
            fields = ('title', 'slug', 'content', 'category', 'image')
            template_name = "create.html"
            success_url = '/'
    
            def form_valid(self, form):
                self.object = form.save(commit=False)
                self.object.user = self.request.user
                self.object.save()
                return HttpResponseRedirect(self.get_success_url())
    

    这对我有用

    【讨论】:

      【解决方案3】:

      (已编辑,因为您尝试的确实有效)

      我昨天遇到了同样的问题,但它现在可以工作了——我想我在 get_initial 返回一个对象而不是一个字典。

      在解决您的问题方面,我有点怀疑您在 post() 中所做的工作 - 您可以尝试使用默认(非覆盖)post() 吗?

      您还可以使用pdb(或打印语句)检查self.get_form_kwargs 的值,确保设置了initial

      【讨论】:

        猜你喜欢
        • 2012-10-22
        • 1970-01-01
        • 2018-07-09
        • 1970-01-01
        • 2016-03-31
        • 2015-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多