首页 > 解决方案 > UpdateView 不保存数据,在 url 中返回对象字段数据

问题描述

无法找出为什么 django 中的 UpdateView 在保存时没有保存表单数据。相反,当它将我重定向回未编辑的对象详细信息视图时,它将数据保存在 url 中。

我正在为 CreateView 和 UpdateView 共享相同的模板

这是我的 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

这是我的 urls.py(应用内 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"),
]

这是呈现 blogpost.html 的 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 %}

这是我在 UpdateView 上点击 Save 后收到的 GET 请求

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]

在这里,get 请求中的“first+edit”是我试图保存在 UpdateView 表单中但进入 url 并且对象未更改的内容。

保存后如何保存对博客所做的编辑?

标签: pythonhtmldjangoformsmodelform

解决方案


在您的表单中, 的值method="PUT"无效,请参阅方法属性文档,因此它回退到method="GET",这就是为什么您在点击保存后收到 GET 请求,并且UpdateView在发送请求时不保存任何数据GET

要解决此问题,method请将表单中的值更改为POST.

然后你必须改变形式的逻辑。不要使用{% if "update" in request.get_full_path %}看起来像一个可靠的黑客的东西 - 如果你改变你的路径,urls.py这将停止工作。或者如果有人?update=foolyou随意输入网址,它也会行为不端。而不是你应该依赖object模板上下文中的缺席/存在,即。像这样的东西:

{% 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 %}




推荐阅读