MultipleObjectsReturned:get()返回了DetailView上的多个对象

时间:2019-02-27 05:26:32

标签: django django-views

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)

我希望用户能够看到由独特的识别的特定文章的详细视图。如果文章是公开的或由当前用户创作的而不是公开的,则用户应有权访问该文章的详细信息视图。作者是我的用户模型的外键。我的ListView中具有相同的get_queryset()逻辑,它确实提供了我想要的内容,但是,当我单击任何文章以请求详细信息视图时,都会收到MultipleObjectsReturned异常。另一个注意事项是django_debug_toolbar表示视图正在发送重复的查询。查询数和返回的对象数相等,因此我需要弄清楚为什么它发送重复的查询,这可能是由外键关系引起的。

2 个答案:

答案 0 :(得分:1)

def get_queryset(self):
    return Article.objects.exclude(Q(is_public=False), 
                                  ~Q(author=self.request.user))

我找到了解决方案!在发布本文之前,我不了解Q对象。在这种情况下,否定Q对象的功能非常方便。此处的逻辑是,我仅排除当前用户以外的用户的非公开文章。

答案 1 :(得分:0)

在您的 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)