How can I program a dynamic sitemap in django, mine not working

445 views Asked by At

The static part works fine but the dynamic posts of my blog app are not generated

from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from .models import Post

class PostSitemap(Sitemap):
    changefreq = "weekly"
    priority = 0.9

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

I'm not able to get a dynamic sitemap with my blog and my Post class in models:

class Post(models.Model):
title=models.CharField(max_length=100)
header_image = models.ImageField(null=True , blank=True, upload_to="images/")
title_tag=models.CharField(max_length=100)
author= models.ForeignKey(User, on_delete=models.CASCADE)
body = RichTextUploadingField(extra_plugins=
['youtube', 'codesnippet'], external_plugin_resources= [('youtube','/static/ckeditor/youtube/','plugin.js'), ('codesnippet','/static/ckeditor/codesnippet/','plugin.js')])
#body = models.TextField()
post_date = models.DateTimeField(auto_now_add=True)
category = models.CharField(max_length=50, default='uncategorized')
snippet = models.CharField(max_length=200)
likes = models.ManyToManyField(User, blank=True, related_name='blog_posts')

def total_likes(self):
    return self.likes.count()

class Meta:
    verbose_name = "Entrada"
    verbose_name_plural = "Entradas"
    ordering = ['-post_date']

def __str__(self):
    return self.title + ' | ' + str(self.author)

def get_absolute_url(self):
    return reverse('home')

If any one can help me I would be very grateful. urls.py:

from django.contrib.sitemaps.views import sitemap
from theblog.sitemaps import PostSitemap, StaticSitemap
        
        sitemaps = {'static': StaticSitemap, 'blog': PostSitemap}
1

There are 1 answers

1
willeM_ Van Onsem On BEST ANSWER

Short answer: The get_absolute_url() should implement a canonical URL to the object.

In order to generate the sitemap. Django will call the .location(…) method [Django-doc] of the Sitemap object on each element. If no .location(…) method is defined, as is the case here. It will call the .get_absolute_url(…) method [Django-doc] on the model object.

You implemented a get_absolute_url method, but it looks like:

def get_absolute_url(self):
    return reverse('home')

this means that all the "detail pages" for the Post objects are apparently the home page, so this is the only page that will be in the sitemap. It is also not really satisfying the conditions of the .get_absolute_url(…) method:

Define a get_absolute_url() method to tell Django how to calculate the canonical URL for an object. To callers, this method should appear to return a string that can be used to refer to the object over HTTP.

A canonical URL means that it is normally unique per object. So if you have a path defined like:

    path('post/<int:pk>', post_details, name='post_details')

then often the canonical url is:

def get_absolute_url(self):
    return reverse('post_details', kwargs={'pk': self.pk})