我正在尝试使用模板标记为我的博客网站实现JSON-LD元数据:
@register.inclusion_tag('common_content/json-ld.html', takes_context=True)
def page_json_ld(context):
"""
Renders JSON-LD for a page
:param context: parent template context
:type context: dict
:return: context for json-ld template
:rtype: dict
"""
site_url = '{}://{}'.format(
context['request'].scheme,
context['request'].get_host()
)
json_ld = {
'@context': 'http://schema.org',
'@type': 'WebPage',
'name': context['menu_link'].page.title,
'url': site_url + context['request'].path,
'description': context['menu_link'].page.meta_description,
'image': {
'@type': 'imageObject',
'url': site_url + context['menu_link'].page.featured_image.url,
'height': context['menu_link'].page.featured_image.height,
'width': context['menu_link'].page.featured_image.width
},
}
return {'json_ld': json.dumps(json_ld, indent=2)}
json-ld.html
模板:
<script type="application/ld+json">
{{ json_ld|safe }}
</script>
以下是我要为以下目的实现JSON-LD的models.py
应用的pages
:
from django.db import models
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from tinymce import models as tinymce
from filebrowser.fields import FileBrowseField
class Page(models.Model):
"""
Represents a rich-text page that is not a blog post, e.g 'About me'
"""
title = models.CharField(verbose_name=_('Page Title'), max_length=200)
keywords = models.CharField(verbose_name=_('Keywords'), max_length=200, blank=True)
content = tinymce.HTMLField(verbose_name=_('Page Content'))
last_updated = models.DateTimeField(verbose_name=_('Last Updated'), auto_now=True)
featured_image = FileBrowseField(verbose_name=_('Featured Image'), max_length=1024,
extensions=['.jpg', '.jpeg', '.png'], blank=True)
meta_description = models.TextField(verbose_name=_('Description'), max_length=160, blank=True)
def __str__(self):
return self.title
class Meta:
verbose_name = _('Page')
#Translators: General plural without a number
verbose_name_plural = _('Pages')
ordering = ('title',)
class MenuLinkQuerySet(models.QuerySet):
"""Custom QuerySet for MenuLinks"""
def have_pages(self):
"""Get MenuLinks that have attached pages"""
return self.filter(page__isnull=False)
class MenuLink(models.Model):
"""
Represents a link in the site navigation menu
"""
caption = models.CharField(verbose_name=_('Caption'), max_length=200)
slug = models.SlugField(verbose_name=_('Slug'), max_length=200, unique=True)
page = models.ForeignKey(Page, verbose_name=_('Page'), blank=True, null=True)
show_side_panel = models.BooleanField(verbose_name=_('Show side Panel'), default=False)
position = models.PositiveIntegerField(verbose_name=_('Position'), default=0, blank=False, null=False)
objects = MenuLinkQuerySet.as_manager()
def get_absolute_url(self):
return reverse('pages:page', kwargs={'slug': self.slug})
def __str__(self):
return self.caption
class Meta:
verbose_name = _('Menu Link')
verbose_name_plural = _('Menu Links')
ordering = ('position',)
如您所见,我使用FileBrowseField
的{{1}}为页面添加特色图片。
所有这些操作都可以在Django开发服务器(django-filebrowser
)上正常运行,即在浏览器中显示一个页面,并正确呈现JSON-LD。但是,当我尝试为相应的视图运行测试时,由于以下原因,测试失败了:
manage.py runserver
失败的测试用例:
File "/home/roman/Projects/romans_blog/pages/templatetags/pages_tags.py", line 45, in page_json_ld
'url': site_url + context['menu_link'].page.featured_image.url,
AttributeError: 'str' object has no attribute 'url'
所以问题是:为什么相同的代码在开发服务器和测试运行器中的行为不同?也就是说,为什么from django.core.urlresolvers import reverse
from django.test import TestCase
from .models import Page, MenuLink
class PageViewTestCase(TestCase):
def test_opening_page_view(self):
page = Page(title='Lorem Ipsum', content='<b>Lorem ipsum dolor sit amet.</b>')
page.save()
link1 = MenuLink(caption='Page 1', slug='page-1', page=page)
link1.save()
link2 = MenuLink(caption='Page 2', slug='page-2')
link2.save()
response = self.client.get(reverse('pages:page', kwargs={'slug': 'page-1'}))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Lorem ipsum dolor sit amet.')
response = self.client.get(reverse('pages:page', kwargs={'slug': 'page-2'}))
self.assertEqual(response.status_code, 404)
字段在开发服务器中具有正确的类型,却在测试期间被强制转换为page.featured_image
?
答案 0 :(得分:0)
事实证明,这是我的错误:我的测试模型实例没有特色图片,并且要使此代码正常工作,. /path/to/function_file
字段必须保存实际的图片,例如:
featured_image
否则,据我了解,from filebrowser.base import FileObject
from .models import Page
page = Page(
title='Lorem Ipsum',
content='<b>Lorem ipsum dolor sit amet.</b>',
featured_image=FileObject('http://via.placeholder.com/350x150')
)
page.save()
字段的值为空字符串。