模型类中的Django按钮



我正在制作一个库存应用程序,我可以在其中更新我的'home.html'的产品值。

我的proj名称是库存应用名称是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',)

我的应用程序的型号:

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})

和我的家.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>

这是您可以做的,

以表单创建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')

如果您不将instance=the_instance_you_want_to_edit传递给Modelform,它将创建一个新实例。Modelform还将如何知道您要编辑哪种模型实例?

basemodelform。 init

    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。或者,您创建一个表单集,每个表单代表一个库存对象以及" stocks_left"的输入字段。

前者有点iffy,因为如果您将主键错误误认为,则会在不注意的情况下更改错误的库存库存(或在道路上丢下ntotexist错误(。如果您只想更改单个库存,则后者是总的杀伤力。

您有两个选项,任何一个选项都需要另一个页面/模板。一个页面显示您的概述,另一页用于更新库存的库存。概述包含指向单个更新页面的链接。


捕获要从URL编辑的对象的主要键。

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>标签添加到模板中,两个(/-(对于您显示的每个实例的"行"。每个标签的HREF属性应包含该行的实例和元素的"作业"(添加或减去库存(。这两个值将在URL conf中使用,就像我上面描述的...
至于如何正确构建HREF属性;模板标签文档应该有所帮助。
也许是这样:

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

当然,您还需要一个新的视图功能来处理这些URL,但是这些URL应该很难弄清楚。

最新更新