我在django还是个新人,所以请多多包涵。我正在尝试建立一个有关书籍的网站。现在我遇到这样的错误
MultipleObjects返回/ premium / 1 / get()返回了不止一本书-它返回了2个!
我不知道在哪里查找错误。这是我的示例代码。
class PageDetailView(LoginRequiredMixin, generic.View):
def get(self, request, *args, **kwargs):
book = get_object_or_404(Book)
page = get_object_or_404(Page)
user_membership = get_object_or_404(Customer, user=request.user)
user_membership_type = user_membership.membership.membership_type
user_allowed = book.allowedMembership.all()
context = {'object': None}
if user_allowed.filter(membership_type=user_membership_type).exists():
context = {'object': page}
return render(request, "catalog/page_detail.html", context)
跟踪:
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ core \ handlers \ exception.py” 在内部 34. response = get_response(request)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ core \ handlers \ base.py” 在_get_response中 126. response = self.process_exception_by_middleware(e,request)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ core \ handlers \ base.py” 在_get_response中 124. response = wrapd_callback(request,* callback_args,** callback_kwargs)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ views \ generic \ base.py” 鉴于 68. return self.dispatch(request,* args,** kwargs)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ contrib \ auth \ mixins.py” 在派遣中 52. return super()。dispatch(request,* args,** kwargs)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ views \ generic \ base.py” 在派遣中 88. return handler(请求,* args,** kwargs)
获取文件“ C:\ Users \ admin \ thesis \ blackink_website \ catalog \ views.py” 127. book = get_object_or_404(Book)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ shortcuts.py” 在get_object_or_404中 93. return queryset.get(* args,** kwargs)
文件 “ C:\ Users \ admin \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ site-packages \ django \ db \ models \ query.py” 在得到 403.(self.model._meta.object_name,num)
异常类型:MultipleObjects在/ premium / 1 /返回 值:get()返回了不止一本书-它返回了2!
如果信息不足,我将更新帖子。预先感谢。
更新
这是我的模型。py
class Book(models.Model):
title = models.CharField(max_length=200) #i deleted some info to make it shorter
allowedMembership = models.ManyToManyField(Membership, blank=True)
def get_absolute_url(self):
return reverse('book-detail', args=[str(self.id)])
def __str__(self):
return self.title
@property
def pages(self):
return self.page_set.all()
class Page(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True)
file = models.FileField(upload_to='book_content', validators=[pdf_file_extension], help_text="PDF File Only")
timestamp = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.book.title
def get_absolute_url(self):
return reverse('page-detail', args=[str(self.id)])
page_detail.html
{% if user_membership and user_membership.user == request.user %}
{% for content in book.pages %}
<a href="{{ content.get_absolute_url }}" class="site-btn">Read</a>
{% endfor %}
{% else %}
<button class="site-btn" disabled="disabled">VIP</button>
{% endif %}
答案 0 :(得分:1)
MultipleObjectsReturned 异常。 django.core.exceptions 中提供了此异常的基本版本。每个模型类都包含一个子类版本,可用于标识已返回多个对象的特定对象类型。
我假设您正在使用最新的Django版本。从官方网站的最底部切换,以查看基于您自己版本的正确文档。
以下是最适合您的链接。
https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#get-object-or-404
https://docs.djangoproject.com/en/2.1/topics/http/views/#the-http404-exception
只需尝试这样,我还没有测试过,但是我相信它会像我之前已经测试过的那样工作。另外,请查看上面的文档,足以消除此问题。
根据https://docs.djangoproject.com/en/2.1/topics/class-based-...配置您的网址,以便您可以通过page_id
,并且网址格式应类似于path('pages/<int:page_id>', PageDetailView.as_view())
或re_path("^pages/(?<page_id>\d+)$", PageDetailView. as_view())
。
在使用 path(), re_path(), url()时要小心,因为它们具有自己的样式+优势。
在研究Book(父模型)和Page(子模型)之间的关系之后,我将urlpattern从path('pages/<int:page_id>/books/<int:book'
更改为path('pages/<page_id>
,并且page id足以获取相关的书,因为有一个两种模型之间的 ForeignKey 关系。
由于您的视图是 PageDetailView ,因此最好仅传递页面ID以更好地进行设计(如其他人所建议的那样(您也可以根据要求传递多个url参数,但是这里不需要) 。
from django.http import Http404
class PageDetailView(LoginRequiredMixin, generic.View):
def get(self, request, *args, **kwargs):
try:
# page = get_object_or_404(Page)
page_id = self.kwargs["page_id"]
page = Page.objects.get(pk=page_id)
# book = get_object_or_404(Book)
book_id = page.book.pk
book = Book.objects.get(pk=book_id)
# user_membership = get_object_or_404(Customer, user=request.user)
user_membership = Customer.objects.get(user=request.user)
user_membership_type = user_membership.membership.membership_type
user_allowed = book.allowedMembership.all()
context = {'object': None}
if user_allowed.filter(membership_type=user_membership_type).exists():
context = {'object': page}
return render(request, "catalog/page_detail.html", context)
except Book.DoesNotExist:
raise Http404("Book with id {0} does not exist".format(book_id))
except Page.DoesNotExist:
raise Http404("Page with id {0} does not exist".format(page_id))
except Customer.DoesNotExist:
raise Http404("Cutomer does not exist")
except Exception as e:
raise Exception(str(e))
答案 1 :(得分:0)
出现此错误的原因是因为您使用get_object_or_404
来获得一本单本,但是问题是您的查询返回了多本图书。当您用来查找书籍的字段上没有唯一约束时,通常会发生这种情况(例如,通过 title 获取对象,“ Jungle Book”将返回具有相同标题的两本书)。
要解决此问题,请使用保证唯一的字段(例如 id )来获取对象。例如:
urls.py
path('page-details/<str:book_id>/<str:page_id>/', PageDetailView.as_view(), name='page_details'),
views.py
class PageDetailView(LoginRequiredMixin, generic.View):
def get(self, request, *args, **kwargs):
book = get_object_or_404(id=kwargs['book_id'])
page = get_object_or_404(id=kwargs['page_id'])
[...]