django admin “add page” initial datetime from GET parameters

后端 未结 2 808
时光取名叫无心
时光取名叫无心 2021-01-12 21:35

I want to create a link which opens the django admin add page of a model with some fields pre filled.

I checked that it is possible to add parameters to the GET dict

相关标签:
2条回答
  • 2021-01-12 22:24

    It appears the problem is your passing a string when it expects a date. You need to convert your string into a date first.

    You can use the built in python library datetime:

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

    Edit: alecxe correctly pointed out that I was not properly answering your question. With a bit of a searching I found something that might be more relevant.

    According to this answer, Django allows you to replace the GET dictionary before it is processed. Borrowing from this example, it seems feasible that we could intercept your get parameters and replace the string dates with datetime objects in the GET dictionary

        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)
    
    0 讨论(0)
  • 2021-01-12 22:31

    No, it isn't a bug; there's maybe an argument that the default behaviour could be improved, but the existing implementation is a reasonable first pass (as evidenced by the fact that it works on integers, strings, foreign keys, etc). There's enough metadata about the model, and enough deserialization code that it would be possible to do slightly better handling here, but I don't think it's a straight up bug.

    The good news is that there is an official way to handle this; on your ModelAdmin class, define:

    def get_changeform_initial_data(self, request):
    

    This method takes the request, and converts that request into the value that will be passed in as the initial argument to the form on a change list (i.e., an add or edit page in Admin). As you might expect, the default implementation of this method is "take the GET arguments and convert into a dictionary"; if you do some additional handling for the fields that you know to be datetimes, then

    Alternatively, you don't have to use the request object at all. If you know that "Person" objects will always have an initial name of "Unknown", and an initial start date of 1 Jan 2014, then you can just write:

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

    i.e., don't pay any attention to the request data, just populate the initial data manually. Since it's initial data to the form, any existing data on the object will override the value provided in initial, and that initial data will be used without the user needing to provide any GET arguments in their request.

    0 讨论(0)
提交回复
热议问题