Django Sitemap - ' str'对象没有属性' get_absolute_url'错误

时间:2018-04-06 19:53:05

标签: python django

我的网站地图页面上的django项目出现'str' object has no attribute 'get_absolute_url'错误。任何帮助表示赞赏。

这是我的追溯:

回溯:

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\views.py" in inner
  16.         response = func(request, *args, **kwargs)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\views.py" in sitemap
  71.                                       protocol=req_protocol))

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in get_urls
  111.             urls = self._urls(page, protocol, domain)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in _urls
  120.             loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in __get
  68.             return attr(obj)

File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in location
  75.         return obj.get_absolute_url()

Exception Type: AttributeError at /sitemap.xml
Exception Value: 'str' object has no attribute 'get_absolute_url'

我的sitemaps.py文件

from django.contrib import sitemaps
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from deals.models import Deal
from blog.models import Post

class StaticViewSitemap(sitemaps.Sitemap):
    priority = 1.0
    changefreq = 'daily'

    def items(self):
        return ['about', 'contact', 'disclosure', 'terms', 'privacy', 'deals:deals', 'blog:blog']


class BlogSitemap(Sitemap):
    changfreq = "daily"
    priority = 1.0
    location ='/blog'

    def items(self):
        return Post.objects.filter(status='Published')

    def lastmod(self, obj):
        return obj.created


class DealSitemap(Sitemap):
    changfreq = "daily"
    priority = 1.0

    def items(self):
        return Deal.objects.all()

    def lastmod(self, obj):
        return obj.date_added

和我的两个相关模型(Deal和Post),我创建了一个get_absolute_url方法,因为它之前在站点地图上生成了错误:

class Deal(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=140, unique=True)
    description = RichTextUploadingField(default='')
    retailer = models.ForeignKey(Retailer, on_delete=models.CASCADE)
    image = VersatileImageField('deal image',
                               upload_to=deal_upload_path,
                               null=True,
                               blank=True)
    link = models.URLField(max_length=2000, default='')
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    date_added = models.DateField(default=timezone.now)
    date_expires = models.DateField(default=timezone.now)
    price = models.CharField(max_length=140)
    secondary_price = models.CharField(max_length=140, default='')
    likes_total = models.IntegerField(default=1)
    expired = models.BooleanField(default=False)

    def __str__(self):
        return "@{} ({})".format(self.title, self.retailer)

    def _get_unique_slug(self):
        slug = slugify(self.title)
        unique_slug = slug
        num = 1
        while Deal.objects.filter(slug=unique_slug).exists():
            unique_slug = '{}-{}'.format(slug, num)
            num += 1
        return unique_slug

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = self._get_unique_slug()
        super().save()

    def get_label(self):
        if self.date_added > datetime.date.today() - datetime.timedelta(days=4):
            return "<span class='"'notify-badge'"'>new</span>"

        else:
            return ''

    def get_absolute_url(self):
        return reverse('deals:deal_detail', kwargs={'slug': self.slug})

class Post(models.Model):
    STATUS_CHOICES = (
        ('Published', 'Published'),
        ('Draft', 'Draft'),
    )
    title = models.CharField(max_length=100, unique=True)
    body = RichTextUploadingField()
    category = models.ForeignKey(BlogCategory, on_delete=models.CASCADE)
    seo_title = models.CharField(max_length=60, blank=True, null=True)
    seo_description = models.CharField(max_length=165, blank=True, null=True)
    slug = models.SlugField(max_length=200, unique=True)
    image = VersatileImageField('blog image',
                               upload_to='media/blog_images',
                               null=True,
                               blank=True)
    created = models.DateTimeField(db_index=True, auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10, default='Draft', choices=STATUS_CHOICES)

    def get_absolute_url(self):
        return reverse('blog:blog_post', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

和我的urls.py文件及相关信息

from django.contrib.sitemaps.views import sitemap

sitemaps = {
    'static': StaticViewSitemap,
    'blog': BlogSitemap,
    'deals': DealSitemap
}

path('sitemap.xml', sitemap,
         {'sitemaps': sitemaps},
         name='django.contrib.sitemaps.views.sitemap'),

2 个答案:

答案 0 :(得分:3)

您没有正确地关注example的StaticViewSitemap。正如文档所说,从items()返回的元素将传递给location()方法;由于项通常是模型实例,因此此方法的默认实现是调用每个实例的get_absolute_url()方法。在您的情况下,您正在传递URL名称,因此您需要适当地重新定义location() - 再次如示例所示。

def location(self, item):
    return reverse(item)

答案 1 :(得分:0)

请求location()方法的是get_absolute_url()函数:here。如果您绝对确定您的字符串已经是 absolute path,您可以通过以下方式在类中简单地覆盖它:

def location(self, item) :
    return item

这将返回您已经设置的绝对路径。