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