django admin"添加页面" GET参数的初始日期时间

时间:2014-05-09 08:19:00

标签: django django-admin

我想创建一个链接,打开一个模型的django admin添加页面,其中一些字段已预先填充。

我检查过可以将参数添加到添加表单的GET字典中,如:

<a href='/admin/myapp/mymodel/add?name=John'>add new mymodel with name John</a>

(实际上我使用{%url'admin:myapp_mymodel_add'%}获取了网址,但这只是明确的。)

现在这适用于数值,文本值和外键。但是DateTime字段呢?当我尝试通过这样的字段时(我尝试了许多格式,例如“2014-05-09 10:10:00”)我总是得到一个“服务器错误”抱怨:

  

'unicode'对象没有属性'date'

代码行中的

  

django / forms / widgets.py in decompress,第902行

 def decompress(self, value):
        if value:
            value = to_current_timezone(value)
            return [value.date(), value.time().replace(microsecond=0)] ...
        return [None, None]

其中变量“value”具有我在URL上传递的值...

问题1.我认为服务器代码不应该根据用户传递的值引发异常...这不是django库中的错误吗?

问题2.如何解决我的问题,即通过GET参数将初始日期时间传递给模型的管理“添加”页面?

2 个答案:

答案 0 :(得分:3)

不,这不是一个错误;可能存在一个可以改进默认行为的论点,但是现有的实现是合理的第一遍(正如它对整数,字符串,外键等起作用所证明的那样)。有足够的关于模型的元数据,以及足够的反序列化代码,它可能可能在这里稍微好一点处理,但我不认为它是一个直接的错误

好消息是有一种正式的方法来处理这个问题;在ModelAdmin课程中,定义:

def get_changeform_initial_data(self, request):

此方法接受请求,并将该请求转换为将作为initial参数传递到更改列表(即Admin中的添加或编辑页面)的表单的值。正如您所料,此方法的默认实现是&#34;获取GET参数并转换为字典&#34 ;;如果你对你知道日期时间的字段进行一些额外的处理,那么

或者,您根本不必使用请求对象。如果你知道&#34; Person&#34;对象的初始名称始终为&#34;未知&#34;,初始开始日期为2014年1月1日,那么您可以写下:

class PersonAdmin(ModelAdmin):
    ...
    def get_changeform_initial_data(self, request):
        return {
            'name': 'Unknown',
            'start_date': date(2014, 1, 1)
        }

即,不要关注请求数据,只需手动填充初始数据。由于它是表单的初始数据,因此对象上的任何现有数据都将覆盖initial中提供的值,并且将使用初始数据,而无需用户提供任何GET个参数。

答案 1 :(得分:1)

看来问题是你在预期日期时传递一个字符串。您需要先将字符串转换为日期。

您可以使用内置的python库datetime

 import datetime
 value = datetime.datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
 def decompress(self, value):
     ...

编辑:alecxe正确地指出我没有正确回答你的问题。通过一些搜索,我发现了一些可能更相关的东西。

根据这个answer,Django允许您在处理之前替换GET字典。借用这个例子,我们可以拦截你的get参数并用GET字典中的datetime对象替换字符串日期似乎是可行的

    def add_view(self, request, form_url='', extra_context=None):
        // any extra processing can go here...
        g = request.GET.copy()
        g.update({
            'date':datetime.datetime.strptime(request.GET.get('date'), "%Y-%m-%d %H:%M:%S"),
        })

        request.GET = g
        return super(MyModelAdmin, self).add_view(request, form_url, extra_context)