'str'对象没有属性'attname'

时间:2014-04-01 00:25:38

标签: django django-models django-templates

我正在尝试使用get_next_or_previous_by_FIELD根据标题字段显示指向下一个和上一个对象的链接。 Django 1.6给我这个错误。

模板渲染期间出错 'str' object has no attribute 'attname'

模板中出现错误。

{% with next_lesson=lesson.get_next_by_title %}

在我的模特中。

return self._get_next_or_previous_by_FIELD('title', is_next=True)

这是我的模特。

class LessonManager(models.Manager):
    def all(self):
        return super(LessonManager, self).filter(active=True)

class Lesson(models.Model):
    active = models.BooleanField(default=False)
    title = models.CharField(max_length=65)
    slug = models.SlugField(unique=True)

    objects = LessonManager()

    def __unicode__(self, ):
        return self.title

    class Meta:
        ordering = ['title']

    def get_absolute_url(self):
        return reverse('lesson', args=[str(self.slug)])

    def get_next_by_title(self):
        try:
            return self._get_next_or_previous_by_FIELD('title', is_next=True)
        except Lesson.DoesNotExist:
            return None

    def get_previous_by_title(self):
        try:
            return self._get_next_or_previous_by_FIELD(order='title', is_next=False)
        except Lesson.DoesNotExist:
            return None

这是我的模板。

<a class="col-md-6" href="{{ lesson.get_previous_by_title.get_absolute_url }}" title="{% trans "View previous post" %}">&laquo; {{ lesson.get_previous_by_title.title }}</a>
<a class="col-md-6" href="{{ lesson.get_next_by_title.get_absolute_url }}" title="{% trans "View previous post" %}">&laquo; {{ lesson.get_next_by_title.title }}</a>

以下是所要求的完整回溯。

Environment:


Request Method: GET
Request URL: /tutorials/lesson/lesson-name/

Django Version: 1.6.2
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'blog',
 'ckeditor',
 'tutorials')
Installed Middleware:
('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\Shaun\Desktop\sg\static\templates\tutorials\lesson.html, error at line 22
   'str' object has no attribute 'attname'
   12 :     {% endif %}


   13 :     {% if lesson.get_next_by_timestamp %}


   14 :         <a class="right" href="{{ lesson.get_next_post.get_absolute_url }}">{{ lesson.get_next_post.title|truncatewords:'4' }} &raquo;</a>


   15 :     {% endif %}


   16 : 


   17 :     <div class='clearfix'></div>


   18 : 


   19 :     <h2>{{ lesson.title|upper }}</h2>


   20 :     <p>{{ lesson.content|safe }}</p>


   21 :     


   22 :     <a class="col-md-6" href=" {{ lesson.get_previous_by_title.get_absolute_url }} " title="{% trans "View previous post" %}">&laquo; {{ lesson.get_previous_by_title.title }}</a>


   23 :   <a class="col-md-6" href="{{ lesson.get_next_by_title.get_absolute_url }}" title="{% trans "View previous post" %}">&laquo; {{ lesson.get_next_by_title.title }}</a>


   24 : 


   25 : {% endblock %}

Traceback:
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\core\handlers\base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Shaun\Desktop\sg\src\tutorials\views.py" in single_lesson
  13.     return render_to_response('tutorials/lesson.html', locals(), context_instance=RequestContext(request))
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\shortcuts\__init__.py" in render_to_response
  29.     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\loader.py" in render_to_string
  169.         return t.render(context_instance)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in render
  140.             return self._render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in _render
  134.         return self.nodelist.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in render
  840.                 bit = self.render_node(node, context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\debug.py" in render_node
  78.             return node.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\loader_tags.py" in render
  123.         return compiled_parent._render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in _render
  134.         return self.nodelist.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in render
  840.                 bit = self.render_node(node, context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\debug.py" in render_node
  78.             return node.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\loader_tags.py" in render
  62.             result = block.nodelist.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in render
  840.                 bit = self.render_node(node, context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\debug.py" in render_node
  78.             return node.render(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\debug.py" in render
  88.             output = self.filter_expression.resolve(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in resolve
  585.                 obj = self.var.resolve(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in resolve
  735.             value = self._resolve_lookup(context)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\template\base.py" in _resolve_lookup
  789.                             current = current()
File "C:\Users\Shaun\Desktop\sg\src\tutorials\models.py" in get_previous_by_title
  64.             return self._get_next_or_previous_by_FIELD('title', is_next=False)
File "C:\Users\Shaun\Desktop\sg\lib\site-packages\django\db\models\base.py" in _get_next_or_previous_by_FIELD
  708.         param = force_text(getattr(self, field.attname))

Exception Type: AttributeError at /tutorials/lesson/setting-up-your-django-blog-application/
Exception Value: 'str' object has no attribute 'attname'

1 个答案:

答案 0 :(得分:1)

_get_next_or_previous_by_FIELD不应该是你自称的东西。

你遇到的主要问题是它期待一个Field对象,而不是一个字符串,因此错误。这是因为该方法实际上是由字段类本身创建的curried函数的一部分,而字体类本身在首次导入模型时由模型元类调用。

currying会创建实际的get_next_by_fooget_previous_by_foo方法。实际上,这些只是为Date和Datetime字段创建的。

请注意,未经处理的方法名称以下划线开头,除了Model._meta之外 - 这是一个很好的信号,表明您不应该在自己的代码中使用它。