我制作了一个库存应用,我可以在其中更新我的主页'中的产品价值。
我的项目名称是库存 应用名称是myapp
我面临的问题是每次我从我的主页更新股票的价值时,它都会添加一个新产品,而不是更新我想要的产品! 我正在使用Django提供的ModelsForm类。 使用Django = 1.11和Python = 3.6
我的项目的urls.py:
from django.conf.urls import url,include
from django.contrib import admin
from myapp.views import home
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^myapp/', include('myapp.urls', namespace="myapp")),
url(r'^myapp/home/', home, name='home'),
]
我的forms.py:
from django import forms
from .models import Inventory
class Operations(forms.ModelForm):
class Meta:
model = Inventory
fields = ('stocks_left',)
我的应用的Model.py:
from django.db import models
import uuid
class Inventory(models.Model):
"""
Model representing a the inventory.
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
inventory_name = models.CharField("INVENTORY NAME" ,max_length=200, help_text="This contains the Inventory name:")
short_name = models.CharField(max_length=20, help_text="This contains an abbreviation:")
inventory_code = models.IntegerField("INVENTORY CODE" ,default = '0', help_text="This contains the Inventory code:")
price = models.IntegerField(default = '0')
stocks_left = models.IntegerField("STOCKS LEFT",default = '0')
def __str__(self):
"""
String for representing the Model object (in Admin site etc.)
"""
return '{0} ({1}) ({2})'.format(self.inventory_name,self.inventory_code,self.stocks_left)
我的应用程序的urls.py
from django.conf.urls import url
from . import views
from django.contrib.auth.views import login
app_name= 'myapp'
urlpatterns = [
url(r'^$', login, {'template_name': 'myapp/login.html'}),
]
和我的views.py
from django.shortcuts import render,redirect
from django.contrib import auth
from django.contrib.auth.models import User
from django.views import generic
from django.http import HttpResponse
from myapp.models import Inventory
from .forms import Operations
def home(request):
names = Inventory.objects.all()
if request.method == "POST":
form = Operations(request.POST)
if form.is_valid():
stocks_left = form.save(commit=False)
stocks_left.save()
return redirect('myapp/home.html')
else:
form = Operations()
return render(request, 'myapp/home.html', { "names": names, "form": form})
和我的home.html模板:
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<title>Inventory</title>
</head>
<body>
<h1>Welcome!</h1>
<div class="container">
<table border="5" cellpadding="10" width="1000">
<thead align="center">
<tr>
<th align="center">#</th>
<th align="center">Name</th>
<th align="center">Inventory Code</th>
<th align="center">Stocks left</th>
<th align="center">Operations</th>
</tr>
<tr>
{% for x in names %}
<td align="center"> {{ x }}</td>
<td align="center"> {{ x.inventory_name }}</td>
<td align="center"> {{ x.inventory_code }}</td>
<td align="center"> {{ x.stocks_left }}</td>
<td><form method="POST">{% csrf_token %}{{form}}<button type="button" class="btn btn-primary"><span class="glyphicon glyphicon-plus"></span></button></form><br></td>
</tr>
{% endfor %}
</table>
</div>
</body>
答案 0 :(得分:0)
这是你可以做的,
在表单中创建2个字段,
class Operations(forms.ModelForm):
class Meta:
model = Inventory
fields = ('stocks_left','inventory_name')
在视图中获取数据时,
if request.method == "POST":
form = Operations(request.POST)
if form.is_valid():
inv_obj = form.cleaned_data.get('inventory_name')
inv_model_obj = Inventory.objects.get(inventory_name=inv_obj) #make sure to declare in the models that this inventory_name is unique
inv_model_obj.stocks_left = form.cleaned_data.get('stocks_left')
inv_model_obj.save()
return redirect('myapp/home.html')
答案 1 :(得分:0)
如果你没有将instance=the_instance_you_want_to_edit
传递给ModelForm,它将创建一个新实例。那么ModelForm怎么会知道你想要编辑的模型实例呢?
BaseModelForm。的初始化强>
if instance is None:
# if we didn't get an instance, instantiate a new one
self.instance = opts.model()
object_data = {}
else:
self.instance = instance
object_data = model_to_dict(instance, opts.fields, opts.exclude)
无论如何,如果你想把它全部保存在一个页面上,它真的不会很好用。您可以手动键入object_id以便稍后传递给ModelForm。或者您创建一个FormSet,每个Form表示一个Inventory对象加上'stocks_left'的输入字段。
前者有点不确定,因为如果你错误输入了主键,你就会在没有注意的情况下更改错误库存的库存(或者在路上抛出一个DoesNotExist错误)。 如果你只想改变一个库存,那么后者总是过度杀伤。
您有两个选项,其中一个选项需要另一个页面/模板。 一页显示您的概览,另一页用于更新库存的库存。概述包含指向各个更新页面的链接。
从网址中捕获要编辑的对象的主键。
url(r'^myapp/home/([0-9]+)/$)', home, name='home-update')
然后,URL调度程序将使用请求和捕获的参数调用home
视图函数,您可以使用它来实例化ModelForm。
def home(request, pk):
names = Inventory.objects.all()
if request.method == "POST":
form = Operations(request.POST, instance=Inventory.objects.get(pk=pk)
if form.is_valid():
form.save()
return redirect('myapp/home.html')
else:
form = Operations()
return render(request, 'myapp/a_very_basic_template_to_display_a_form.html', {"form": form})
或者使用基于类的UpdateView(用于“更新”页面):
class InventoryStockUpdateView(views.generic.UpdateView):
model = Inventory
template_name = 'myapp/a_very_basic_template_to_display_a_form.html'
fields = ['stocks_left']
success_url = reverse_lazy('home')
在urls.py中有这个:
url(r'^myapp/home/(?P<pk>[0-9]+)/$)', InventoryStockUpdateView.as_view(), name='home-update')
要使用主键31415编辑库存,您可以在浏览器中输入“... home / 31415”。
更新: 您是否看过django的管理操作?它们允许您通过复选框选择实例,然后对它们运行管理操作,从而更改更改列表中的实例。虽然这可能不是你想要的,但调查它们的工作原理应该会教你一些能帮助你完成当前任务的技巧。
或许可以为您提供一些指示:向您的模板添加<a>
标签,为您正在显示的每个“行”添加两个(+/-)。
a的每个标记的href属性应包含行的实例和元素的“作业”(添加或减去股票)。这两个值将在url conf中使用,就像我上面描述的那样......
至于如何正确构建href属性; template tag docs应该有所帮助
也许是这样:
<tr>
{% for x in names %}
<td align="center"> {{ x }}</td>
<td align="center"> {{ x.inventory_name }}</td>
<td align="center"> {{ x.inventory_code }}</td>
<td align="center"> {{ x.stocks_left }}</td>
<td><a href={% url ??? %}>click me to subtract!</a></td>
<td><a href={% url ??? %}>click me to add!</a></td>
</tr>
{% endfor %}
当然,您还需要一个新的视图功能来处理这些网址,但这些并不是很难理解。