I am having some problems with sitemaps.
urls.py
from django.contrib import sitemaps
from oportunidade.views import OportunidadeSitemap
sitemaps = {'oportunidade': OportunidadeSitemap}
...
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
views.py
...
class OportunidadeSitemap(Sitemap):
changefreq = "never"
priority = 0.5
def items(self):
return Oportunidade.objects.filter(ativo=True)
def lastmod(self, obj):
return obj.ultima_alteracao
But I get the following error when I access http://localhost:8000/sitemap.xml
'Oportunidade' object has no attribute 'get_absolute_url'
Here is my "Oportunidade" model:
class Oportunidade(models.Model):
user = models.ForeignKey(User)
titulo = models.CharField('Titulo',max_length=31)
...
def __unicode__(self):
return self.titulo
I am very confused how to set sitemap.
Please take a look at Django's sitemap class reference. Although you implement the necessary items method, you seem to be missing either the location method (or attribute) in your sitemap or the get_absolute_url method in you model class.
If location isn't provided, the framework will call the get_absolute_url() method on each object as returned by items().
Easiest way to go forward would be to implement get_absolute_url() in you Oportunidade model class.
According to the docs: https://docs.djangoproject.com/en/1.3/ref/contrib/sitemaps/#sitemap-class-reference
If you don't provide a location for the sitemap class, it will look for get_absolute_url on each object.
So, you'll either need to specify a location property on your sitemap class, or get_absolute_url on your object. That should get you going.
Related
I am trying to create a sitemap in Django but I am getting an error
'Post' object has no attribute 'get_absolute_url'
Here is my anotherfile/sitemap.py
from django.contrib.sitemaps import Sitemap
from somefile.models import Post
class site_map(Sitemap):
changefreq = "daily"
priority = 0.8
def items(self):
return Post.objects.all()
def lastmod(self, obj):
return obj.time_stamp
and here is my somefile/models.py
class Post(models.Model):
number=models.AutoField(primary_key=True)
slug=models.CharField(max_length=130)
time_stamp=models.DateTimeField(blank=True)
def __str__(self):
return self.number
In order to determine the paths in the sitemap, you need to implement a get_absolute_url for the model(s) for which you make a sitemap, so:
from django.urls import reverse
class Post(models.Model):
number=models.AutoField(primary_key=True)
slug=models.CharField(max_length=130)
time_stamp=models.DateTimeField(blank=True)
def get_absolute_url(self):
return reverse('name-of-some-view', kwargs={'para': 'meters'})
def __str__(self):
return self.number
With reverse(…) [Django-doc] you can calculate the URL based on the name of the view, and parameters that the corresponding path needs.
I've never used it, but it simply sounds like your Post model doesn't have a get_absolute_url method.
http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/#django.contrib.sitemaps.Sitemap.location
If location isn't provided, the framework will call the
get_absolute_url() method on each object as returned by items().
Model.get_absolute_url()
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.
For example:
def get_absolute_url(self):
return "/post/%i/" % self.id
In my views.py I have a class who take a (CreateView) and in the form_class take a Testform in forms.py
The problem is when in my forms.py I use the def save(...) method, it save correctly the data but the is no way to reverse after that
it say to me no matter what I try to return it says
"No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model."
ok, so I've tried everywhere to put this method but no way, it allways gives me this error
It depends on where you want to redirect the user after creating a new object.
Example setup:
CreateView is configured with url r'^mymodel/new/', name='mymodel_create' in urls.py.
DetailView is configured with url r'^mymodel/:pk/', name='mymodel_detail' in urls.py.
You can define get_absolute_url like this:
class MyModel(Model):
# field definitions...
def get_absolute_url(self):
return reverse('mymodel_detail', kwargs={'pk': self.pk})
Creating a new object will then redirect to the DetailView.
I know this is really simple, but I'm missing something. And because I can't ever remember this, I'm hoping this can document a solution here.
All I want to do is pass a PK for the object in the URL and get the detail view back.
Url:
url(regex=r'^(?P<pk>\d+)/$',
view=AdventureDetail.as_view(),
name='adventure_detail',
),
View:
class AdventureDetail(DetailView):
""" Get a time entry detail view """
template_name = "adventure/AdventureDetail.html"
def get_object(self):
return get_object_or_404(Page)
But I'm getting a "multiple objects returned error"
MultipleObjectsReturned at /1/
get() returned more than one Page -- it returned 5! Lookup parameters were {}
This feels really silly. It should "just work" but I'm missing something obvious.
Thanks for the help.
In DetailView it is more simpler: you can just specify the model:
class AdventureDetail(DetailView):
""" Get a time entry detail view """
model = Page
template_name = "adventure/AdventureDetail.html"
And that's all. DetailView will do the rest of work.
Another way is to specify queryset:
class AdventureDetail(DetailView):
""" Get a time entry detail view """
queryset = Page.objects.all()
template_name = "adventure/AdventureDetail.html"
This will have the same result.
And the last way is to override the get_object method.
Look here for details
You're not passing any other parameters to get_object_or_404, other than the Page class. So now you're basically querying for all pages. So you'd need to do:
return get_object_or_404(Page, pk=self.kwargs.get('pk', None))
Also, why are you overriding get_object? The DetailView already contains this functionality so all you need to do is have a URL with pk in it.
In views.py
from django.views.generic import DetailView
# Import your model that you want to use in details view for example
from .models import Post
class PostDetailView(DetailView):
model = Post
Then create a template with the following name conversion
<appname>/<model_viewtype>.html
In urls.py
First import the class view that you created. In our case it is
from .views import PostDetailView
Then
path("post/<int:pk>/", views.PostDetailView.as_view(), name="PostDetailView")
What is #permalink and get_absolute_url in Django? When and why to use it?
Please a very simple example (a real practical example). Thanks
As of 2013, the Django documentation discouraged use of the permalink decorator and encouraged use of reverse() in the body of the get_absolute_url method. By 2015, the permalink decorator seemed to have vanished without a trace from the Django documentation, and it was finally removed in Django version 2.1 in 2018.
So, for a standard DRY way to create a permanent link to a single object view, use get_absolute_url() in your model like this:
from django.db import models
from django.urls import reverse
# NOTE: pre Django 1.10+ this is "from django.core.urlresolvers import reverse"
class MyModel(models.Model):
slug = models.SlugField()
def get_absolute_url(self):
return reverse('mymodel_detail', args=(self.slug,))
and then have an entry in urls.py that points to your view:
url(r'^(?P<slug>[-\w\d\_]+)/$',
MyModelDetailView.as_view(),
name='mymodel_detail'),
#permalink is a python decorator, while get_absolute_url is a method on a django model.
Both are concerned with allowing you to reverse the URL for a particular object and should be used together. They are used anytime you need to provide a link to a particular object or want to display that object's specific URL (if it has one) to the user
You could simply write your get_absolute_url method to return a hard coded string, but this wouldn't adhere to Django's philosophy of DRY (don't repeat yourself). Instead, there is the #permalink to make things more flexible.
If you read the docs on the subject you will see how they relate to each other. the #permalink decorator hooks into django's URLconf's backend, allowing you to write much more portable code by using named url patterns. This is preferable to just using get_absolute_url on it's own: your code becomes much DRYer as you don't have to specify paths.
class BlogPost(models.Model):
name = modelsCharField()
slug = models.SlugField(...)
#permalink
def get_absolute_url(self):
return ("blog-detail", [self.slug,])
and in urls.py
...
url(r'/blog/(?P<slug>[-w]+)/$', blog.views.blog_detail, name="blog-detail")
in Django 2.1
The django.db.models.permalink() decorator is removed.
source
A better approach is to declare a name for your app in urls.py and then refer to that instead of hard coding anything:
in urls.py:
app_name = 'my_app'
urlpatterns = [
path('blogs/<int:slug>', blog.views.blog_detail, name='mymodel_detail'),
]
and in models.py:
from django.urls import reverse
class BlogPost(models.Model):
name = modelsCharField()
slug = models.SlugField(...)
def get_absolute_url(self):
return ('my_app:mymodel_detail, args=[self.slug,])
How do I wrap a Django Form Wizard in a view? I need to do this so I can access request.
Does anyone have some example code for this?
I probably should be just commenting on Manoj's answer, but sounds you need code
urls.py
from django.conf.urls.defaults import *
from MyApp import views
urlpatterns = patterns(
'',
(r'^wizard/$', views.MyWizardView ),
)
views.py
#login_required
def MyWizardView (request):
cw = MyWizard([WizardName, WizardQuestions, WizardProvider, WizardGoomber])
return cw(request)
The as_view function converts a class based view into a callable view:
from django import forms
from django.contrib.formtools.wizard.views import SessionWizardView
class Form1(forms.Form):
a = forms.CharField()
class Form2(forms.Form):
b = forms.CharField()
class MyWizard(SessionWizardView):
pass
wizard_view = MyWizard.as_view([Form1, Form2])
def view(request):
# do something fancy with the request object here
return wizard_view(request)
This is basicly the same answer as in How to wrap a Django Form Wizard in a View?
This Django snippet may prove useful.
From the title: "FormWizard inside view with proper context handling and site templating support, without having to use urls.py"