12👍
✅
You can work with the fact that items
may return anything that can be passed to the other methods of a Sitemap
:
import itertools
class SchoolSitemap(Sitemap):
# List method names from your objects that return the absolute URLs here
FIELDS = ("get_absolute_url", "get_about_url", "get_teachers_url")
changefreq = "weekly"
priority = 0.6
def items(self):
# This will return you all possible ("method_name", object) tuples instead of the
# objects from the query set. The documentation says that this should be a list
# rather than an iterator, hence the list() wrapper.
return list(itertools.product(SchoolSitemap.FIELDS,
School.objects.filter(status = 2)))
def location(self, item):
# Call method_name on the object and return its output
return getattr(item[1], item[0])()
If the number and names of fields are not predetermined, I would go for a completely dynamic approach: Allow models to have a get_sitemap_urls
method that returns a list of absolute URLs, and use a Sitemap
that executes this method. That is, in the simplest case where you do not need to have access to the objects in the priority/changefreq/lastmod methods:
class SchoolSitemap(Sitemap):
changefreq = "weekly"
priority = 0.6
def items(self):
return list(
itertools.chain.from_iterable(( object.get_sitemap_urls()
for object in
School.objects.filter(status = 2)))
)
def location(self, item):
return item
Source:stackexchange.com