Django - 带有赋值的自定义标签
Django - custom tags with assigning values
我正在尝试在 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() missing 1 required positional argument: 'topic_id'
我尝试在没有变量名的块中使用标签,但仍然出现同样的错误。
这是完整的追溯
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获取item的方法
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
这个问题其实和模板标签无关
您已将 get_item_with_topic_id
定义为一个实例方法,它将 self
作为其第一个参数。但是你直接在评论 class 上调用它,所以没有涉及实例并且 self
没有被传递 - 所以 Python 认为你正在传递 [=14= 的值] 代替 self
并且根本没有通过 topic_id
。
您可以通过将其声明为 class 方法并使用 cls
代替 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
。
(顺便说一句,你确定查询是正确的吗?不应该是.get(topic_id=topic_id)
吗?)
我正在尝试在 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() missing 1 required positional argument: 'topic_id'
我尝试在没有变量名的块中使用标签,但仍然出现同样的错误。
这是完整的追溯
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获取item的方法
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
这个问题其实和模板标签无关
您已将 get_item_with_topic_id
定义为一个实例方法,它将 self
作为其第一个参数。但是你直接在评论 class 上调用它,所以没有涉及实例并且 self
没有被传递 - 所以 Python 认为你正在传递 [=14= 的值] 代替 self
并且根本没有通过 topic_id
。
您可以通过将其声明为 class 方法并使用 cls
代替 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
。
(顺便说一句,你确定查询是正确的吗?不应该是.get(topic_id=topic_id)
吗?)