Django - 分配值为

时间:2017-10-29 13:07:24

标签: python django tags backend

我正在尝试在django中构建自己的标签。

这是我定义标记时的代码:

@register.inclusion_tag('post/templates/comment_block')
def limit_amount_in_a_page(starting_index, topic_id=1, amount=5):
    comments = Comment.get_item_with_topic_id(topic_id)
    selected_comments = []
    for index in range(starting_index, starting_index+amount):
        selected_comments.append(comments[index])
    return {'selected_comments': selected_comments}

这就是我使用它的方式:

<div class="past_comments">
    {% limit_amount_in_a_page starting_index=0 topic_id=1 amount=5 %}
</div>

这是模板:

<ul>
{% for comment in selected_comments %}
<li>
    <div class="comment_body">
    <div class="user_info_block">
        <div class="content">
            <div class="photo_profile"></div>
            <div class="user_info"></div>
        </div>
    </div>
    <div class="content_block">

        <p>{{comment.content}}</p>
    </div>
    </div>
</li>
{% endfor %}

但是,我得到了这个例外:

  

get_item_with_topic_id()缺少1个必需的位置参数:&#39; topic_id&#39;

我尝试在没有变量名的块中使用标记,但仍然有相同的错误。

这是完整的追踪

Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/post/1/

Django Version: 1.11.3
Python Version: 3.6.2
Installed Applications:
['post.apps.PostConfig',
 'music.apps.MusicConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
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                         C:\Users\Nutzer\PycharmProjects\selfTry\post\templates\post\detail.html, error         at line 16
   get_item_with_topic_id() missing 1 required positional argument: 'topic_id'   6 :     <meta charset="UTF-8">
   7 :     <title>{{topic.topic}}</title>
   8 :     <link rel="stylesheet" type="text/css" href="{% static 'post/comment_block.css' %}">
   9 :     <link rel="stylesheet" type="text/css" href="{% static 'post/detail_base.css' %}">
   10 : </head>
   11 : <body>
   12 :     <div class="topic">
   13 :         {{topic.topic}}
   14 :     </div>
   15 :     <div class="past_comments">
   16 :          {% limit_amount_in_a_page page_nr=0 topic_id=1 amount=5 %} 
   17 :         {% if starting_index is 0 %}
   18 :         <a href="#">Last Page</a>
   19 :         {% endif %}
   20 :         <a href="#">Next Page</a>
   21 :     </div>
   22 : 
   23 :     <div class="leave_a_comment">
   24 :         <form action = "{% url 'post:comment' topic_id=topic.id user_id=1 %}" method="post">
   25 :             {% csrf_token %}
   26 :             {{ form.as_p }}


Traceback:

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-    packages\django\core\handlers\exception.py" in inner
  41.             response = get_response(request)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\Nutzer\PycharmProjects\selfTry\post\views.py" in detail
  26.         'comments': comments,

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\shortcuts.py" in render
  30.     content = loader.render_to_string(template_name, context, request, using=using)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\loader.py" in render_to_string
  68.     return template.render(context, request)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\backends\django.py" in render
  66.             return self.template.render(context)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\base.py" in render
  207.                     return self._render(context)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\base.py" in render
  990.                 bit = node.render_annotated(context)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
  957.             return self.render(context)

File "C:\Users\Nutzer\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\library.py" in render
  225.         _dict = self.func(*resolved_args, **resolved_kwargs)

File "C:\Users\Nutzer\PycharmProjects\selfTry\post\templatetags\post_tags.py" in limit_amount_in_a_page
  13.     comments = Comment.get_item_with_topic_id(topic_id)

Exception Type: TypeError at /post/1/
Exception Value: get_item_with_topic_id() missing 1 required positional     argument: 'topic_id'

然后是从sqlite

获取项目的方法
class Comment(models.Model):
class Meta:
    unique_together = (('commenter_id', 'date'),)

topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
commenter_id = models.IntegerField()
date = models.DateTimeField(auto_now=True)
content = models.CharField(max_length=9999999)

def __str__(self):
    return "comment from " + str(self.commenter_id) + " on " + str(self.date)

def get_item_with_topic_id(self, topic_id):
    comments = self.objects.get(id=topic_id)
    return comments

1 个答案:

答案 0 :(得分:0)

这个问题实际上与模板标签无关。

您已将get_item_with_topic_id定义为实例方法,该方法将self作为其第一个参数。但是你直接在Comment类上调用它,所以没有涉及实例并且self没有被传递 - 所以Python认为你在{{1}的位置传递topic_id的值并且根本没有传递self

您可以通过将此声明为类方法并将topic_id替换为cls来解决此问题,但您不应该这样做;像这样的自定义查询方法属于Manager,而不是模型。所以:

self

现在您的模板标记可以调用class CommentManager(models.Manager): def get_item_with_topic_id(self, topic_id): comments = self.get(id=topic_id) return comments class Comment(models.Model): ... objects = CommentManager()

(顺便说一下,你确定查询是对的吗?不应该是Comment.objects.get_item_with_topic_id吗?)