首页 文章

Django模板标记,用于将当前请求中的GET参数添加到Python3 Django2中的url

提问于
浏览
0

我正在尝试将我的项目从Python 2.7 / Django 1.11迁移到Python 3.7 / Django 2.1 .

在我的项目中,来自以下django片段的've used ' 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_ ...

1 回答

  • 1

    解决方案非常简单 . 感谢@BearBrown

    Variable(value).resolve(context) param应该转换为字符串

    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()
    

相关问题