【问题标题】:MultipleObjectsReturned: get() returned more than one object on DetailViewMultipleObjectsReturned:get() 在 DetailView 上返回了多个对象
【发布时间】:2019-02-27 05:26:32
【问题描述】:

views.py

class ArticleDetail(DetailView):
    model = Article

    def get_queryset(self):
        public_articles = Article.objects.filter(is_public=True)
        private_authored_articles = Article.objects.filter(is_public=False, author=self.request.user)
        return public_articles.union(private_authored_articles)

urls.py

path('articles/<slug:slug>/', views.ArticleDetail.as_view(), name='article-detail')

models.py

class Article(models.Model):
    ...
    title = models.CharField(max_length=255, default='', blank=False)
    slug = models.SlugField(unique=True, editable=False)
    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Article, self).save(*args, **kwargs)

我希望用户能够查看由唯一 slug 标识的特定文章的详细视图。如果文章是公开的或者是由当前用户创作的并且不是公开的,则用户应该有权访问文章的详细视图。作者是我的用户模型的外键。我的 ListView 中有同样的 get_queryset() 逻辑,它给了我我想要的东西,但是当我单击任何文章请求详细视图时,我得到 MultipleObjectsReturned 异常。另一个注意事项是 django_debug_toolbar 表示视图正在发送重复的查询。查询的数量和返回的对象的数量是相等的,所以我需要弄清楚它为什么发送重复的查询,可能是由外键关系引起的。

【问题讨论】:

  • urls.py 中的 url 是什么?这是完整的ArticleDetail 视图吗?
  • 我还覆盖了 get_context_data,发送了一些额外的上下文。省略该部分,因为这不应该是异常的原因。
  • URL 中的 slug 部分是什么?您在哪里进行基于此的过滤?多篇文章中可能存在同一个 slug 吗?
  • slug 是 Article 上的 SlugField,约束为 unique=True。因此,要回答您的问题,不,多篇文章中没有相同的蛞蝓。查询集不应基于 slug 进行过滤。它的目的是检索可能显示在 DetailView 中的候选文章。
  • slug_field 设置是否正确?

标签: django django-views


【解决方案1】:
def get_queryset(self):
    return Article.objects.exclude(Q(is_public=False), 
                                  ~Q(author=self.request.user))

我找到了解决方案!在发表这篇文章之前,我不知道 Q 对象。在这种情况下,否定 Q 对象的能力非常方便。这里的逻辑是我只排除当前用户以外的用户的非公开文章。

【讨论】:

    【解决方案2】:

    在您的 views.py 中检查以下参数并确保定义slug 字段如下:

    class ArticleDetail(DetailView):
        model = Article
        slug_field = 'slug_field'  # Replace `slug_field` with your SlugField on Article model
        slug_url_kwarg = 'slug'
    
        def get_queryset(self):
            public_articles = Article.objects.filter(is_public=True)
            authored_articles = Article.objects.filter(author=self.request.user)
            return public_articles.union(authored_articles)
    

    【讨论】:

      猜你喜欢
      • 2020-08-14
      • 2021-06-24
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多