问题
Suppose this view that is for edit record:
def edit_post(request, slug):
post = get_object_or_404(Post, slug=slug)
if request.method == "POST":
form = AddPostForm(request.POST, request.FILES, instance=post)
# 1
if form.is_valid():
# 2
new_post = form.save(commit=False)
new_post.save()
return redirect('administrator:view_admin_post')
...
Now assume these:
I have
field1
that is exist inPOST
model.field1
has default value and suppose that the current value offield1
depends on previous.- Also suppose that I don't want to pass the
field1
to user. As a result, I will not have it inrequest.POST
.
In this situation when I write print(post.field1)
In line # 1
I have previous value but when I print that in
line # 2
I got None
!
What is going on?And how can I have my post.field1
?
Notice: I know I can define a middleware variable and save the previous value in this variable.But is there a better way to do this?
回答1:
First point: .is_valid()
will NOT touch your database (unless you customize the form's validation, but then, well, you'd know why xD). It's the call to Model.save()
(either directly or thru form.save()
) that overwrites the previous value.
Second point: if you pass a model instance to your form (which is what you do), you can access it (and it's fields) thru {{ form.instance.your_field_name }}
in the template.
And finally, you can either totally exclude a model field from the ModelForm, or mark it as read-only.
All of this is rather well documented FWIW, so I kindly suggest you take some time reading the doc before going any further with bizarre and convoluted "solutions" (hint: you definitly don't need a middleware to get the original value, it's still in your database - until you overwrite it, that is).
来源:https://stackoverflow.com/questions/56451143/why-executing-form-is-valid-cause-deleting-of-the-instance-fields-that-arent