#298 closed enhancement (wontfix)
Need impovement to POST.copy()
Reported by: | mr_little | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When i need to change only few fields of model, for example only date_start field of Project, i need to pass a values of other fields like new_data variable into manipulator.* methods ('coz they are not present in POST)
The only place of values of other fields is Project.dict
But manipulator.* methods expects new_data.values() like strings. And Project.dict contains .values() like python-values.
Also, new_data must be MultiValueDict
So, i need to make new_data like this (it's a simple shortened example without checks):
def start(req, p_id): """ Updates "start" information about project Such as start_date, start_people e.t.c. """ try: prj = projects.get_object(pk=rp_id) except projects.ProjectDoesNotExist: raise Http404 manipulator = projects.ChangeManipulator(prj.id) new_data = prj.__dict__ # all fields of Project errors = dict() if req.POST: #only tree fields changed, and values of them are in req.POST new_data = update_post(req.POST.copy(), new_data) errors = manipulator.get_validation_errors(new_data) mnp.do_html2python(new_data) mnp.save(new_data)
Where the update_post() is like this:
def update_post(post, data): for key in data: if not key in post.keys(): if data[key]: post[key]=str(data[key]) else: post[key]='' return post
But it's easy to say:
new_data = req.POST.copy(new_data) # default values like param #or new_data.update(req.POST)
or something like this...
Change History (6)
comment:1 by , 19 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 19 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Look at example:
Model Project, has
project_name
date_start
date_end
The view StartProject has only one form-field and submit button
[date_start] [OK]
when we starting project - it's no need to change it's name or date_end
I want to use manipulator's form fields to draw, and to validate that 'start_date'
So, when i press [OK], request.POST in code contains only that field {'start_date':date}
but it doesn't contains 'project_name' and 'date_end' fields which are required for manipulator.save() method
So i need to emulate:
- get that fields from Project.dict
- transform it to strings (becoz manipulator's validators expects strings, not python values)
- add that fields to new_data dict
There are would be clear if step 1 - 3 will be a "feature" of POST.copy() method
Simply - when i pass Project.dict to the POST.copy() method it get's values from that dict, and adds that values to the result, like strings.
So, manipulator thoughs that fields a passed from the POST request :)
comment:3 by , 19 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
The thing is, request.POST emulates a dictionary, and in Python dict.copy() doesn't take an argument. It seems stupid to have a dict-like object that deviates from the object it's emulating.
Besides, this is extremely easy to do:
new_data = project.__dict__ new_data = new_data.update(request.POST.copy())
That's clear, concise, and immediately obvious, whereas:
new_data = request.POST.copy(Project.__dict__)
Might be shorter, but is unclear -- is Project.__dict__
overriding values in request.POST
, or is it the other way around? For that matter, what's getting copied?
comment:4 by , 19 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
two mistakes in your example:
1.
new_data = project.__dict__ # new data type is dict new_data = new_data.update(request.POST.copy()) # new data type is dict but must be MultiValueDict like request.POST
- values in new_data are python values from
project.__dict__
but must be strings (for validators)
The second condition is worst :(
comment:5 by , 19 years ago
from utils.datastructures import MultiValueDict new_data = MultiValueDict(dict([(k, [str(v)]) for (k, v) in project.__dict__.items()])) new_data = new_data.update(request.POST.copy())
that should do the trick and convert all values to strings.
comment:6 by , 19 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
Please explain this better. I don't really understand what you're trying to do.