使用模型按标题使用Django上一个和下一个对象

时间:2014-03-31 18:48:10

标签: python django django-models django-templates

我想根据标题显示上一课和下一课的链接。我正在尝试使用get_next_by_title在我的模型中执行此操作。

如果有更简单的方法或有使用自定义get_next_or_prev_by_FIELD的官方文档,请指出正确的方向。

使用Django 1.6。

这是我的models.py。

class Lesson(models.Model):
    tutorials = models.ForeignKey('Tutorial', blank=True)
    title = models.CharField(max_length=65)
    slug = models.SlugField(unique=True)

    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('title', is_next=False)
        except Lesson.DoesNotExist:
            return None

这是我的模板。

   {% with prev_lesson=lesson.get_previous_by_title %}
    {% if prev_lesson %}
      <a class="col-md-6" href="{{ prev_lesson.get_absolute_url }}">&laquo; {{ prev_lesson.title }}</a>
      <div class="col-md-6"></div>
    {% endif %} {% endwith %} {% with next_lesson=lesson.get_next_by_title %}
    {% if next_lesson %}
      <a class="col-md-6" href="{{ next_lesson.get_absolute_url }}">&laquo; {{ next_lesson.title }}</a>
    {% endif %} {% endwith %}

这是完整的回溯请求。

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 :(得分:0)

Django DateTimeField仅添加get_previous_by_。如果你想通过标题,你必须创建自己的方法。它没有显示任何内容,因为Django模板系统无声地失败。

Django Model类有一个_get_next_or_previous_by_FIELD,您可以创建以下内容:

class MyModel(models.Model):
    [fields]

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

    def get_previous_by_title(self):
        try:
            return self._get_next_or_previous_by_FIELD('title', is_next=False)
        except MyModel.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>