Why executing form.is_valid() cause deleting of th

2019-09-19 15:15发布

问题:

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:

  1. I have field1 that is exist in POST model.

  2. field1 has default value and suppose that the current value of field1 depends on previous.

  3. Also suppose that I don't want to pass the field1 to user. As a result, I will not have it in request.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).