Python FormView不会更新,但会创建模型的新记录

Python FormView不会更新,但会创建模型的新记录,python,django,Python,Django,我使用的是基于类的视图 我使用的是FormView,但如果需要,可以打开以更改为UpdateView 我的主要目标是,在访问模型的列表名称后,如果需要,我可以更改其名称 访问一个特定列表的URL,在该URL中,用户应该看到与该特定列表相关的所有元素,并且可以使用表单更新其名称 path('lista-detalles/<int:lista_id>/', views.ListDetailsFormView.as_view(), name='list_details'), views.

我使用的是基于类的视图

我使用的是FormView,但如果需要,可以打开以更改为UpdateView

我的主要目标是,在访问模型的列表名称后,如果需要,我可以更改其名称

访问一个特定列表的URL,在该URL中,用户应该看到与该特定列表相关的所有元素,并且可以使用表单更新其名称

path('lista-detalles/<int:lista_id>/', views.ListDetailsFormView.as_view(), name='list_details'),
views.py:

奖励:我想回到同一个页面,显示当前列表及其项目的页面

更新1:

我已经使用了UpdateView,但是表单仍然创建了一个新的对象,而不是更新

视图:

HTML:

html:


创建表单时需要传递实例,但也就是说,可以使用


创建表单时需要传递实例,但也就是说,可以使用



创建表单时需要传递实例,但也就是说,使用UpdateView可以消除很多样板文件。@WillemVanOnsem请提供一个工作示例。@OmarGonzales Django有很好的文档记录。你为什么不先搜索一下医生?@Brunodesshuilliers据此:https://ccbv.co.uk/projects/Django/3.0/django.views.generic.edit/UpdateView/ 我只需要执行self.object=form.save in form\u valid。但这仍然会创建一个新对象。Willem的回答是,有点帮助,但仍然创建了一个新对象。@OmarGonzales我刚才说的是Django的文档。例如,创建表单时需要传递实例,但也就是说,通过使用UpdateView可以消除很多样板文件。@WillemVanOnsem请提供一个工作示例。@OmarGonzales Django有很好的文档记录。你为什么不先搜索一下医生?@Brunodesshuilliers据此:https://ccbv.co.uk/projects/Django/3.0/django.views.generic.edit/UpdateView/ 我只需要执行self.object=form.save in form\u valid。但这仍然会创建一个新对象。Willem的回答是,有点帮助,但仍然创建了一个新对象。@OmarGonzales我刚才说的是Django的文档。例如。得到这样的结果:必须在URLconf中使用对象pk或slug调用通用详细视图ListDetailsFormView。@OmarGonzales:是的,您需要在此处指定pk_url_kwarg,因为它不是“pk”,这仍然会创建一个新对象,而不是更新当前对象。在我最初的问题中,我已经有了:def form_validself上的form.instance.name=self.request.name, form@OmarGonzalez:它通常应该编辑通过lista_id主键传递主键的项目。@WillemVanOnsem是否确实要将form.instance.name=request.name行保持为form_有效?得到以下信息:必须使用对象pk或slug在URLconf@OmarGonzales:是的,您需要在这里指定pk_url_kwarg,因为它不是“pk”,这仍然会创建一个新对象,而不是更新当前对象。在我最初的问题中,我已经有了:def form_validself上的form.instance.name=self.request.name,form@OmarGonzalez:它通常应该编辑通过lista\u id主键传递主键的项目。@WillemVanOnsem是否确实要使form\u中的form.instance.name=request.name行保持有效?
class List(models.Model):
    LISTA_STATUS = (
        ('recibida_pagada', 'Recibida y pagada'),
        ('recibida_no_pagada', 'Recibida pero no pagada'),
        ('en_revision', 'En revision'),
        ('en_camino', 'En camino'),
        ('entregada', 'Entregada'),
        ('cancelada', 'Cancelada')
    )
    name = models.CharField(max_length=100, default='Lista anónima')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    school = models.OneToOneField(School, on_delete=models.CASCADE, null=True, blank=True)
    status = models.CharField(max_length=20, choices=LISTA_STATUS, default='recibida_no_pagada')
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        return str(self.id)
from django.shortcuts import get_list_or_404, get_object_or_404
class ListDetailsFormView(LoginRequiredMixin, FormView):
    form_class = ListForm
    template_name = "scolarte/listas/lista-detalles.html"

    def get(self, request, lista_id, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        lista = get_object_or_404(List, id=lista_id)
        data_dict = {'name': lista.name,}
        form = ListForm(initial=data_dict)
        context['form'] = form
        list_items = ListItem.objects.filter(lista=lista)
        context['list_items'] = list_items
        total = 0
        for list_item in list_items:
            total += Decimal(list_item.sub_total())
        context['total'] = total

        return self.render_to_response(context)

    def form_valid(self, lista_id, form):
        # instance = get_object_or_404(List, id=lista_id)
        # form = ListForm(request.POST or None, instance=instance)
        # form = form.save(commit=False)
        # form.user = self.request.user  
        # form.save()
        form.instance.name = self.request.name
        form.save()
        return super(ListDetailsFormView, self).form_valid(form)


    def get_success_url(self):
        return reverse_lazy('lists:list_details', kwargs={'lista_id': self.kwargs['pk']})
class ListDetailsFormView(LoginRequiredMixin, UpdateView):
    model = List
    form_class = ListForm
    context_object_name = 'lista'
    pk_url_kwarg  = 'lista_id'
    template_name = "scolarte/listas/lista-detalles.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['list_items'] = ListItem.objects.filter(lista=self.object)
        return context

    def form_valid(self, form):
        form.instance.name = self.request.name
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('lists:list_details', kwargs={'lista_id': self.object.pk})
{% extends 'scolarte/base.html' %}

{% load crispy_forms_tags %}

{% block content %}

<!-- <h1>Mi lista: {{ lista.name }}</h1> --> 


<div class="row">
    <form action="{% url 'lists:my_lists' %}" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Submit">
    </form>
</div>



<div class="row">
    {% for list_item in list_items %}
        {% if forloop.counter0|divisibleby:3 and not forloop.first %}<div class="w-100"></div>{% endif %}
        <div class="card margin-right3" style="width: 14rem;">
            <div class="card-body">
              <h5 class="card-title">{{ list_item.product.short_name }}</h5>
              <p class="card-title">$ {{ list_item.product.price }}</p>
              <p class="card-text">{{ list_item.description }}</p>
            </div>
        </div> 
    {% endfor %}
</div>

{% endblock %}
AttributeError at /listas/lista-detalles/14/
'WSGIRequest' object has no attribute 'name'
<div class="row">
    <form action="{% url 'lists:list_details' lista.id %}" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Submit">
    </form>
</div>
from django.views.generic.edit import UpdateView

class ListDetailsFormView(LoginRequiredMixin, UpdateView):
    model = List
    form_class = ListForm
    context_object_name = 'lista'
    pk_url_kwarg  = 'lista_id'
    template_name = "scolarte/listas/lista-detalles.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['list_items'] = ListItem.objects.filter(lista=self.object)
        return context

    def form_valid(self, form):
        form.instance.name = self.request.name
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('lists:list_details', kwargs={'lista_id': self.object.pk})
from django.views.generic.edit import UpdateView

class ListDetailsFormView(LoginRequiredMixin, UpdateView):
    model = List
    form_class = ListForm
    context_object_name = 'lista'
    pk_url_kwarg  = 'lista_id'
    template_name = "scolarte/listas/lista-detalles.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['list_items'] = ListItem.objects.filter(lista=self.object)
        return context

    def get_success_url(self):
        return reverse('lists:list_details', kwargs={'lista_id': self.object.pk})