简体   繁体   中英

UpdateView Doesn't Save Data, returns object field data in url

Can't find out why UpdateView in django wasn't saving form data upon being saved. Instead, it saved the data in a url when it redirected me back to an un-edited object detail view.

I'm sharing the same template for CreateView and UpdateView

Here's my Views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.views import View

from .models import Blog
from .forms import BlogForm

from django.views.generic import (
  CreateView,
  ListView,
  DetailView,
  UpdateView,
  DeleteView
)
class BlogListView(ListView):
  template_name = 'blogtemplates/blogs.html'
  queryset = Blog.objects.all()
  model = Blog
  paginate_by = 4

  def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # Add in a QuerySet of all the books
    context['object_list'] = Blog.objects.all()
    return context

class BlogDetailView(DetailView):
  model = Blog
  template_name = 'blogview.html'
  queryset = Blog.objects.all()

  def get_object(self):
    id_ = self.kwargs.get("pk")
    return get_object_or_404(Blog, id=id_)

  def get_context_data(self, **kwargs):

    context = super().get_context_data(**kwargs)
    # Add in a QuerySet of all the books
    context['object_list'] = Blog.objects.all()
    return context

class BlogCreateView(CreateView):
  template_name = 'blogpost.html'
  form_class = BlogForm
  queryset = Blog.objects.all()

  def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context
    context = super().get_context_data(**kwargs)
    # Add in a QuerySet of all the books
    context['object_list'] = Blog.objects.all()
    return context

class BlogUpdateView(UpdateView):
  template_name = 'blogpost.html'
  form_class = BlogForm

  def get_object(self):
    id_ = self.kwargs.get("pk")
    return get_object_or_404(Blog, id=id_)
  
  def get_context_data(self, **kwargs):
    # Call the base implementation first to get a context
    context = super().get_context_data(**kwargs)
    # Add in a QuerySet of all the books
    context['object'] = self.get_object()
    context['object_list'] = Blog.objects.all()
    print(context['object'])
    return context

Here's my urls.py (in-app urls.py)

from django.urls import path

from .views import (
  BlogListView, 
  BlogCreateView,
  BlogDetailView, 
  BlogUpdateView, 
  #BlogDeleteView
  )
app_name = 'blogs'
urlpatterns = [
  path('', BlogListView.as_view(), name='blog-list'),
  path('<int:pk>/', BlogDetailView.as_view(), name="blog-detail"),
  path('post/', BlogCreateView.as_view(), name="blogs-post"),
  path('<int:pk>/update', BlogUpdateView.as_view(), name='blogs-update')
  #path('<int:pk>/delete', BlogDeleteView.as_view(), name="blog-delete"),
]

Here's The HTML Template that is rendered blogpost.html

{% extends 'base.html' %}

{% block content %}
{% if request.user.username == 'Thorba' %}
  <div class="container-fluid bg-5 text-center">
  {% if "update" in request.get_full_path %}
    <form action="." method="PUT">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save"/>
    </form>
  {% else %}
    <form action="." method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save"/>
    </form>
  {% endif %}
 </div>
{% else %}
  <div class="container-fluid bg-5 text-center">
    <h1 class="box li">Permission Denied</h1>
  </div>
{% endif %}
{% endblock %}

Here's the GET request I get after hitting Save on the UpdateView

HTTP GET /11/?csrfmiddlewaretoken=F4syRqsTW8X8JtPPSpzpu6qsCf7lryMOlGAnqHFelFt2XuzWCVQaeHEeoINOLnvR&title=And+Yet+%E2%80%A6+Another+Blog&description=POST+METHOD+CHECK&blog=After+a+LOT+of+research+about+UpdateView%2C+I+still+haven%27t+found+a+way+to+SAVE+THE+DATA.+The+url+is+routing+the+UpdateView+correctly+but+after+hitting+save+it+redirects+me+to+the+same%2C+previous%2C+unedited+object+First+Edit 200 [0.01, 192.168.29.226:51360]

Here, the 'first+edit' in the get request is what I had tried to save in the UpdateView form but instead went into the url and the object came out unchanged.

How do I Save the edits I make to the blog after I save it?

in your form the value of method="PUT" is not valid, see method attribute docs , so it fallbacks to method="GET" , which is why you are getting GET request after hitting save, and UpdateView does not save any data when it's dispatching GET request.

To fix this, change method value in your form to POST .

Then you have to change the logic of form. Don't use things like {% if "update" in request.get_full_path %} it seems like an ureliable hack - if you'd change the path in your urls.py this will stop working. Or if someone would put ?update=foolyou into the url arbitrarily, it will also misbehave. Rather than that you should rely on abesnce/presence of object in your template context, ie. something like this:

{% if object %} # existing object, do update

<form action="{% url "blogs-update" pk=object.pk %}" method="POST">

{% else %} # object not present, creating new one

<form action="." method="POST">

{%e endif %}



The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM