首页 > 解决方案 > 如何将主键传递给 url Django

问题描述

我基本上有3个问题

  1. 我试图在创建它之后在 url 中传递供应商的主键,但是当我进入供应商页面时,它显示错误“Reverse for 'vendorCategory' with arguments '('',)' not found。尝试了 1 种模式:['vendorCategory/(?P<vendor_id>[0-9]+)/$']'

  2. 在供应商类别中,当我尝试针对特定供应商存储多个产品时,它会显示错误“Field id int but You got ['12', '11']”

  3. 在供应商类别模板中,当我选择任何类别时,它只显示我添加的最后一个类别

视图.py

class Vendor(TemplateView):

     template_name = 'purchase/vendor.html'

     def get(self, request, *args, **kwargs):
         return render(request, self.template_name)

     def post(self, request, vendor_id):
        try:
           data = self.request.POST.get
           vendor = VendorModel(
                name=data('name'),
                email=data('email'),
                Contact_No=data('Contact_No'),
                address=data('address')
           )
           vendorId = vendor.objects.get(pk=vendor_id)
           vendor.save()
           
           return redirect('vendorCategory', args={'vendor': vendorId})
        except Exception as e:
           return HttpResponse('failed{}'.format(e))


class Vendor_Category(TemplateView):

    template_name = 'purchase/vendorCategory.html'

    def get(self, request, vendor_id=None, *args, **kwargs):
        categories = CategoryModel.objects.all()
        categoryId = self.request.GET.get('SelectCategory')
        products = ProductModel.objects.filter(category_id=categoryId)
        vendor= VendorModel.objects.get(id=vendor_id)
        args = {'categories': categories, 'products': products, 'selectedCategory':  categoryId, 'vendor': vendor}
        return render(request, self.template_name, args)

   def post(self, request):

       categoryobj = self.request.GET.get('SelectCategory')
       productobj = self.request.POST.getlist('ProductSelect')

       try:
          vendor = VendorCategory(
              vendor_id=self.request.vendor_id,
              category_id=categoryobj,
              product_id=productobj

          )
          vendor.save()
          return redirect('menu')
       except Exception as e:
           return HttpResponse('failed{}'.format(e))

网址.py

urlpatterns = [

   path('vendorCategory/<int:vendor_id>/', Vendor_Category.as_view(), name='vendorCategory')
   path('vendor', Vendor.as_view(), name='vendor'),
]

模板

VendoreCategory.html

   {% extends 'auth/home.html' %}

  {% block content %}

<form method="get">
{% csrf_token %}
    <label>
        <select name="SelectCategory" >
        <option disabled="disabled" value="True" selected="{{ selectedCategory|yesno:"yes, no"|safe }}"> Select Category</option>
            {% for category in categories %}
            <option value="{{ category.id }}" selected="{% if category.id == selectedCategory %} {% endif %}">
                {{ category.name }}
            </option>
            {% endfor %}
        </select>
    </label>

    <input type="submit" value="Select">
</form>
<form method="post">
<input type="hidden" value={{  selectedCateogry }} name="ProductSelect">
{% csrf_token %}
<label>
    {% for product in products%}
    <input type="checkbox" name="ProductSelect" value="{{ product.id }}" >{{ product.name }}
    {% endfor %}
    </label>
<input type="submit" value="Select">


</form>

{% endblock %}

供应商.html

   {% extends 'auth/home.html' %}

{% block content %}
<form method="post">
 {% csrf_token %}
    <label for="name">Name
        <input type="text" name="name" id="name" placeholder="Enter vendor name">
    </label>
    <label for="email">Email
        <input type="email" name="email" id="email" placeholder="Enter vendor's email address">
    </label>
    <label for="Contact_No">Contact no
        <input type="number" name="Contact_No" id="Contact_No" placeholder="Enter vendor contact no">
    </label>
    <label for="address">Address
        <input type="text" name="address" id="address" placeholder="Enter vendor address">
    </label>
    <button type="submit">Submit </button>
</form>
 {% endblock %}

标签: pythondjango

解决方案


我认为您的问题是您正在扩展 a TemplateView,然后将其视为 a View

如果你覆盖 aTemplateView你应该阅读方法中的 kwargs get_context_data。如果您更喜欢“动手方法”(就像我自己一样),那么摆脱TemplateView并扩展 normal View,然后覆盖getandpost方法(就像您现在正在做的那样)。

from django.views import View

编辑:我又看了一遍

错误一:

也许试试这个?

def get(self, request, *args, **kwargs):
    categories = CategoryModel.objects.all()
    categoryId = self.request.GET.get('SelectCategory')
    products = ProductModel.objects.filter(category_id=categoryId)
    vendor= VendorModel.objects.get(id=self.kwargs['vendor_id'])
    args = {'categories': categories, 'products': products, 'selectedCategory':  categoryId, 'vendor': vendor}
    return render(request, self.template_name, args)

在 URL 中,您要求提供一个 kwarg (vendor_id),但我没有看到您在任何地方使用它。每次您转到该路径并且无法指定请求的 kwarg 时,也会出现该错误。因此,当您尝试运行 VendorCategory 视图时,请确保您的网址末尾有 /1/ 或其他内容。

错误2:

您正在尝试将列表分配给 int 变量。难怪它不起作用。我的建议是添加:

print(self.request.POST.getlist('ProductSelect'))

在您的发布方法中,看看会发生什么。然后,您可以设计一种方法来打开它并存储它。我的意思是,我们已经知道它是一个列表.. 所以你显然不能为你正在创建的单个对象分配多个 id。您应该首先创建一个供应商,然后有一个产品创建循环将产品添加到该供应商。像这样的东西可能会起作用:

categoryobj = self.request.GET.get('SelectCategory')
productobj = self.request.POST.getlist('ProductSelect')

try:
  vendor = VendorCategory.objects.create(
      vendor_id=self.request.vendor_id,
      category_id=categoryobj,
  )
  vendor.save()
  for product_id in productobj:
    product = ProductModel.objects.get(id=product_id)
    product.vendormodel = vendor
    product.save()

现在..我认为你在哪里写错了,vendor = VendorCategory(或者至少我从未见过这种语法,我不知道它应该完成什么。在我的版本中,我将其替换为,VendorCategory.objects.create因为这就是我假设您正在尝试做的事情。

错误 3:

在模板中,您正在使用|yesno带有值的过滤器int。您是否想了解是否有 id?

您正在运行一个for循环,您可能会在其中选择多个值,在这种情况下,该项目应该有一个“多个”。 <select name="asdsad" multiple>

我觉得奇怪的是你有一个<label>包装整个<select>. <label>应该有,for="field_id"就是这样。除了非常特殊的情况。

最后但并非最不重要的一点是,您有一个错字:

<input type="hidden" value={{  selectedCateogry }} name="ProductSelect">

推荐阅读