Django:get()返回了多个项目 - 它返回3

时间:2018-01-24 10:25:02

标签: python django

我收到了错误

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

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

Model.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

视图功能进行编辑。 Views.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

4 个答案:

答案 0 :(得分:0)

您需要为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,以遵循单一命名惯例。

答案 1 :(得分:0)

只需浏览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或任何其他fild传递给get_object_or_404,如:get_object_or_404(MyModel,pk = 1)

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

答案 2 :(得分:0)

正如其他答案所指出的那样,您需要在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 %}

答案 3 :(得分:0)

用于编辑的固定购买功能 - 更正

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)