【问题标题】:Django: get() returned more than one items -- it returned 3Django:get() 返回了不止一项——它返回了 3
【发布时间】:2018-01-24 10:25:01
【问题描述】:

我遇到了一个错误

MultipleObjectsReturned: get() returned more than one items -- it returned 3!.

我想编辑和更新数据库中的现有记录。下面是我的模型、视图和 html 代码。

模型.py

import datetime
from django.db import models
from django.utils import timezone

class Purchases(models.Model):
    bottle = models.CharField(max_length=20)
    bottle_purchased = models.CharField(max_length=20)
    date_added = models.DateTimeField(auto_now_add=True)
    bottle_total= models.CharField(max_length=20)
    transportation_cost = models.CharField(max_length=20)
    total_cost = models.CharField(max_length=20)

        class Meta:
            verbose_name_plural = 'Purchases'

        def __str__(self):
            return self.bottle

用于编辑的视图功能。 视图.py

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse

from .models import Purchases
from .forms import PurchasesForm


def purchases(request):
    purchases = Purchases.objects.order_by('date_added')
    context = {'purchases': purchases}
    return render(request, 'ht/purchases.html', context)

def edit_purchase(request):
    entry = get_object_or_404(Purchases)
    purchase = entry.purchase

    if request.method != 'POST':
        # Initial request; pre-fill form with the current entry
        form = PurchasesForm(instance=entry)
    else:
        # POST data submitted; process data.
        form = PurchasesForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('geo_gas:purchases'))

    context = {'entry': entry, 'purchases': purchases, 'form': form}
    return render(request, 'geo_gas/edit_purchase.html', context)

edit_purchase.html

    <form action="{% url 'geo_gas:edit_purchase' %}" method='post'>
    {% csrf_token %}
    {{ form.as_p}}
    <button name="Submit">save changes</button>
    </form>

附加的是返回的错误。

get() returned more than one items -- it returned 3!

enter image description here

【问题讨论】:

  • 问题出在你的entry = get_object_or_404(Purchases)。您必须指定主键才能仅获取 1 条记录。
  • 请为edit_purchase添加您的网址格式。
  • 网址格式'路径('edit_purchase/', views.edit_purchase, name='edit_purchase'),'
  • 不要发布代码截图。在 django 错误日志页面中,您可以切换到可复制粘贴的视图。改用它或控制台输出。

标签: python django


【解决方案1】:

只需浏览 django 文档 https://docs.djangoproject.com/en/2.0/topics/http/shortcuts/#get-object-or-404

它在内部调用 get() https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.get

如果找到多个对象,它将引发 MultipleObjectsReturned。

您需要将 primary_key 或任何其他字段传递给 get_object_or_404,例如:get_object_or_404(MyModel, pk=1)

如果你想要多条记录,也可以使用 filter()。

【讨论】:

    【解决方案2】:

    正如其他答案所指出的,您需要过滤get_object_or_404 中的查询集,以便它只返回一个对象。但是下一个问题是您如何知道要获取哪个对象?

    编辑页面的常用方法是在 url 模式中包含主键或唯一 slug:

    path('edit_purchase/<int:pk>/', views.edit_purchase, name='edit_purchase'),
    

    然后您需要更新视图以接受新参数,并在get_object_or_404 中使用它。

    def edit_purchase(request, pk):
        entry = get_object_or_404(Purchases, pk=pk)
    

    最后,你需要在反转 URL 时包含参数,例如

    {% url 'geo_gas:edit_purchase' entry.pk %}
    

    【讨论】:

    • 如上所示实施。它失败了。但能够以另一种方式解决它。
    • 我无法发现上述代码有任何问题。 “失败”信息不足以让我了解问题所在。
    • 更新购买视图功能后出现类型错误。 entry = get_object_or_404(Purchases, pk=pk) response = Wrapped_callback(request, *callback_args, **callback_kwargs) TypeError: edit_purchases() missing 1 required positional argument: 'pk'
    • 这听起来像是一个单独的问题,因为问题和答案不会在任何地方使用edit_purchases
    【解决方案3】:

    您需要向get_object_or_404 提供参数,而不仅仅是模型。

    看看get_object_or_404的源码:

    def get_object_or_404(klass, *args, **kwargs):
        """
        Uses get() to return an object, or raises a Http404 exception if the object
        does not exist.
    
        klass may be a Model, Manager, or QuerySet object. All other passed
        arguments and keyword arguments are used in the get() query.
    
        Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
        object is found.
        """
    

    还可以考虑将您的 Purchases 模型命名为 Purchase 以遵循单一命名约定。

    【讨论】:

      【解决方案4】:

      修正购买功能进行编辑-修正

      def edit_purchase(request):
      
              ""Edit an existing purchase record."""
              entry = get_object_or_404(Purchases, pk=1)
              #entry = Purchases.objects.filter(pk='date_added')
              #purchase = entry.purchase
      
              if request.method != 'POST':
                  # Initial request; pre-fill form with the current entry
                  form = PurchasesForm(instance=entry)
              else:
                  # POST data submitted; process data.
                  form = PurchasesForm(instance=entry, data=request.POST)
                  if form.is_valid():
                      form.save()
                      return HttpResponseRedirect(reverse('geo_gas:purchases'))
      
              context = {'entry': entry, 'form': form}
              return render(request, 'geo_gas/edit_purchase.html', context)
      

      【讨论】:

        猜你喜欢
        • 2022-10-23
        • 2020-08-14
        • 2022-06-21
        • 1970-01-01
        • 2013-03-16
        • 2021-06-24
        • 1970-01-01
        • 2016-08-13
        • 1970-01-01
        相关资源
        最近更新 更多