Django 模板标签将当前请求的 GET 参数添加到 Python3+Django2 中的 url
Django template tag to add GET parameters from current request to url in Python3+Django2
我正在尝试将我的项目从 Python 2.7/Django 1.11 迁移到 Python 3.7/Django 2.1。
在我的项目中,我使用了来自以下 Django 片段的 'add_get_parameter' 模板标签:
https://djangosnippets.org/snippets/2428/
add_get_parameter.py
class AddGetParameter(Node):
def __init__(self, values):
self.values = values
def render(self, context):
#req = resolve_variable('request',context) #deprecated in modern Django
req = template.Variable('request').resolve(context)
params = req.GET.copy()
for key, value in self.values.items():
params[key] = Variable(value).resolve(context)
return '?%s' % params.urlencode()
@register.tag
def add_get_parameter(parser, token):
from re import split
contents = split(r'\s+', token.contents, 2)[1]
pairs = split(r',', contents)
values = {}
for pair in pairs:
s = split(r'=', pair, 2)
values[s[0]] = s[1]
return AddGetParameter(values)
在模板中,我用它来制作这样的分页网址:
{% load add_get_parameter %}
<div class="pagination">
<span class="step-links">
{% if device_tests.has_previous %}
<a href="{% add_get_parameter page=device_tests.previous_page_number %}">Previous</a>
{% endif %}
{% for num in device_tests.paginator.page_range %}
{% if num == device_tests.number %}
<span class="current"><b>{{ num }}</b></span>
{% else %}
<a href="{% add_get_parameter page=num %}"> {{ num }}</a>
{% endif %}
{% endfor %}
{% if device_tests.has_next %}
<a href="{% add_get_parameter page=device_tests.next_page_number %}">Next</a>
{% endif %}
</span>
</div>
它在 Python 2.7/Django 1.11 中都有效,但在 Python 3.7/Django 2.1 中无效。
Django 抱怨:
Exception Type: AttributeError
Exception Value: 'int' object has no attribute 'encode'
标记错误字符串在'add_get_parameter.py':
return '?%s' % params.urlencode()
如何解决这个问题?
完整追溯:
Error during template rendering
In template E:\routemaps_python3\trunk\predator\templates\layout.html, error at line 0
'int' object has no attribute 'encode'
1 {% load static from staticfiles %}
2
3 <!doctype html>
4 <html>
5 <head>
6 <meta charset="utf=8">
7 <meta http-equiv="X-UA-Compatible" content="IE=edge">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 <title>{% block title %}{% endblock %}</title>
Traceback Switch to copy-and-paste view
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\exception.py in inner
response = get_response(request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\base.py in _get_response
response = self.process_exception_by_middleware(e, request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
E:\routemaps_python3\trunk\predator\predator\views_errors_feed.py in device_test_errors_feed
return render(request, 'device_test_errors_feed.html', {'device_tests': device_tests}) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\shortcuts.py in render
content = loader.render_to_string(template_name, context, request, using=using) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader.py in render_to_string
return template.render(context, request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\backends\django.py in render
return self.template.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
return self._render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in _render
return self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader_tags.py in render
return compiled_parent._render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in _render
return self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
return nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\templatetags\tz.py in render
output = self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader_tags.py in render
result = block.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
nodelist.append(node.render_annotated(context)) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
return nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
E:\routemaps_python3\trunk\predator\device_tests\templatetags\add_get_parameter.py in render
return '?%s' % params.urlencode() ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\http\request.py in urlencode
for v in list_ ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\http\request.py in <genexpr>
for v in list_ ...
解决方法很简单。感谢@BearBrown
Variable(value).resolve(context)
参数应转换为字符串
class AddGetParameter(Node):
def __init__(self, values):
self.values = values
def render(self, context):
#req = resolve_variable('request',context) #deprecated in modern Django
req = template.Variable('request').resolve(context)
params = req.GET.copy()
for key, value in self.values.items():
params[key] = str(Variable(value).resolve(context))
return '?%s' % params.urlencode()
我正在尝试将我的项目从 Python 2.7/Django 1.11 迁移到 Python 3.7/Django 2.1。
在我的项目中,我使用了来自以下 Django 片段的 'add_get_parameter' 模板标签: https://djangosnippets.org/snippets/2428/
add_get_parameter.py
class AddGetParameter(Node):
def __init__(self, values):
self.values = values
def render(self, context):
#req = resolve_variable('request',context) #deprecated in modern Django
req = template.Variable('request').resolve(context)
params = req.GET.copy()
for key, value in self.values.items():
params[key] = Variable(value).resolve(context)
return '?%s' % params.urlencode()
@register.tag
def add_get_parameter(parser, token):
from re import split
contents = split(r'\s+', token.contents, 2)[1]
pairs = split(r',', contents)
values = {}
for pair in pairs:
s = split(r'=', pair, 2)
values[s[0]] = s[1]
return AddGetParameter(values)
在模板中,我用它来制作这样的分页网址:
{% load add_get_parameter %}
<div class="pagination">
<span class="step-links">
{% if device_tests.has_previous %}
<a href="{% add_get_parameter page=device_tests.previous_page_number %}">Previous</a>
{% endif %}
{% for num in device_tests.paginator.page_range %}
{% if num == device_tests.number %}
<span class="current"><b>{{ num }}</b></span>
{% else %}
<a href="{% add_get_parameter page=num %}"> {{ num }}</a>
{% endif %}
{% endfor %}
{% if device_tests.has_next %}
<a href="{% add_get_parameter page=device_tests.next_page_number %}">Next</a>
{% endif %}
</span>
</div>
它在 Python 2.7/Django 1.11 中都有效,但在 Python 3.7/Django 2.1 中无效。
Django 抱怨:
Exception Type: AttributeError
Exception Value: 'int' object has no attribute 'encode'
标记错误字符串在'add_get_parameter.py':
return '?%s' % params.urlencode()
如何解决这个问题?
完整追溯:
Error during template rendering
In template E:\routemaps_python3\trunk\predator\templates\layout.html, error at line 0
'int' object has no attribute 'encode'
1 {% load static from staticfiles %}
2
3 <!doctype html>
4 <html>
5 <head>
6 <meta charset="utf=8">
7 <meta http-equiv="X-UA-Compatible" content="IE=edge">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9
10 <title>{% block title %}{% endblock %}</title>
Traceback Switch to copy-and-paste view
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\exception.py in inner
response = get_response(request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\base.py in _get_response
response = self.process_exception_by_middleware(e, request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\core\handlers\base.py in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
E:\routemaps_python3\trunk\predator\predator\views_errors_feed.py in device_test_errors_feed
return render(request, 'device_test_errors_feed.html', {'device_tests': device_tests}) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\shortcuts.py in render
content = loader.render_to_string(template_name, context, request, using=using) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader.py in render_to_string
return template.render(context, request) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\backends\django.py in render
return self.template.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
return self._render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in _render
return self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader_tags.py in render
return compiled_parent._render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in _render
return self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
return nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\templatetags\tz.py in render
output = self.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\loader_tags.py in render
result = block.nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
nodelist.append(node.render_annotated(context)) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\defaulttags.py in render
return nodelist.render(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render
bit = node.render_annotated(context) ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\template\base.py in render_annotated
return self.render(context) ...
E:\routemaps_python3\trunk\predator\device_tests\templatetags\add_get_parameter.py in render
return '?%s' % params.urlencode() ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\http\request.py in urlencode
for v in list_ ...
C:\Users\kostr\AppData\Local\Continuum\Anaconda\envs\routemaps3\lib\site-packages\django\http\request.py in <genexpr>
for v in list_ ...
解决方法很简单。感谢@BearBrown
Variable(value).resolve(context)
参数应转换为字符串
class AddGetParameter(Node):
def __init__(self, values):
self.values = values
def render(self, context):
#req = resolve_variable('request',context) #deprecated in modern Django
req = template.Variable('request').resolve(context)
params = req.GET.copy()
for key, value in self.values.items():
params[key] = str(Variable(value).resolve(context))
return '?%s' % params.urlencode()