添加注解注解时出现奇怪的Django错误

qv7cva1a  于 2023-03-20  发布在  Go
关注(0)|答案(1)|浏览(139)

我试图添加评论到我的django论坛,但遇到了一个问题的注解。每当我添加指令添加评论com=Comment.objects.order_by("-published_date")它给我一个问题,一个完全无关的部分,我的模板,检查用户名。
以下是我看法:

def index(request):
    # check if there is any incomming data (comments) and make sure the user is authenticated
    POST = request.POST
    if POST != {} and request.user.is_authenticated:
        # a comment has been recived, time to move forward with creating it

        # figure out if the post even exists
        get_object_or_404(Post, id = POST['post_id'])

        # grab the user object
        user_active = User.objects.get(id = POST['user'])

        # grab the post object
        post_active = Post.objects.get(id = POST['post_id'])

        # make and save the comment
        n_comment = Comment(user = user_active, comment = POST['comment'], post = post_active)
        n_comment.save()

    posts = Post.objects.order_by("-published_date").annotate(num_likes=Count("likes"),com=Comment.objects.order_by("-published_date"))
    return render(request, 'home.html', {'posts': posts})

下面是我模型:

class Comment(models.Model):
    comment = models.CharField(max_length=500)
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')
    published_date = models.DateTimeField('date_published')

这里是错误:

Environment:

Request Method: GET
Request URL: http://localhost:8000/

Django Version: 3.2.18
Python Version: 3.6.9
Installed Applications:
['core',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'accounts']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']

Template error:
In template /vagrant/templates/base.html, error at line 12
   subquery must return only one column
LINE 1: ...d_by_id", COUNT("core_like"."id") AS "num_likes", (SELECT "c...
                                                             ^

   2 : <title>{% block title %}{% endblock %} - Pelican</title>
   3 : 
   4 : {%load static%}
   5 : 
   6 : <link rel='stylesheet' href="{% static 'core/style.css' %}">
   7 : 
   8 : <nav>
   9 :   <h1>Pelican</h1>
   10 :   <ul>
   11 :     {% if user.is_authenticated %}
   12 :       <li><span>{{ u ser.username }}</span>
    13 :       <li><a href="{% url 'logout' %}">Log Out</a>
   14 :     {% else %}
   15 :       <li><a href="{% url 'signup' %}">Sign Up</a>
   16 :       <li><a href="{% url 'login' %}">Log In</a>
   17 :     {% endif %}
   18 :   </ul>
   19 : </nav>
   20 : <section class="content">
   21 :   <header>
   22 :     {% block header %}{% endblock %}

Traceback (most recent call last):
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

The above exception (subquery must return only one column
LINE 1: ...d_by_id", COUNT("core_like"."id") AS "num_likes", (SELECT "c...
                                                             ^
) was the direct cause of the following exception:
  File "/vagrant/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/vagrant/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/vagrant/venv/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/vagrant/core/views.py", line 33, in index
    return render(request, 'home.html', {'posts': posts})
  File "/vagrant/venv/lib/python3.6/site-packages/django/shortcuts.py", line 19, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/template/defaulttags.py", line 171, in render
    len_values = len(values)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/models/query.py", line 262, in __len__
    self._fetch_all()
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/models/query.py", line 51, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
    cursor.execute(sql, params)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/vagrant/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

Exception Type: ProgrammingError at /
Exception Value: subquery must return only one column
LINE 1: ...d_by_id", COUNT("core_like"."id") AS "num_likes", (SELECT "c...
                                                             ^

奇怪的是,每当我删除注解时,一切都正常。现在模板是非常基本的,它应该只显示注解对象。

xyhw6mcr

xyhw6mcr1#

对此不使用注解,如错误所述,Subquery最多只能返回一个项目。
您可以按顺序预取注解,因此:

from django.db.models import Count, Prefetch
from django.shortcuts import redirect

def index(request):
    # check if there is any incomming data (comments) and make sure the user is authenticated
    POST = request.POST
    if request.method == 'POST' and request.user.is_authenticated:
        # a comment has been recived, time to move forward with creating it

        # figure out if the post even exists
        active_post = get_object_or_404(Post, id=POST['post_id'])

        # make and save the comment
        n_comment = Comment(
            user=request.user, comment=POST['comment'], post=post_active
        )
        n_comment.save()
        return redirect('name-of-some-view')

    posts = (
        Post.objects.order_by('-published_date')
        .prefetch_related(
            Prefetch('comments', Comment.objects.order_by('-published_data'))
        )
        .annotate(num_likes=Count('likes'))
    )
    return render(request, 'home.html', {'posts': posts})

在模板中,使用以下项渲染该对象:

{% for post in posts %}
    …
    {% for comment in post.comments.all %}
    {% endfor %}
{% endfor %}

注意:通常使用**settings.AUTH_USER_MODEL[Django-doc]来引用用户模型比直接使用User模型[Django-doc]要好。更多信息请参见文档中的 * refering the User model 部分。
Note:如果POST请求成功,您应该创建一个
*redirect**[Django-doc]来实现Post/Redirect/Get pattern [wiki]。这样可以避免在用户刷新浏览器时,您也会发出相同的POST请求。
注意:最好使用Form [Django-doc],而不是手动验证和清理数据。Form不仅可以简化HTML表单的“呈现”,而且可以更方便地“验证"输入,并将数据”清理“为更方便的类型。

相关问题