I need to make a blog in Django and I have a Blog
class declared as follows:
models.py
class Blog(models.Model):
name = models.CharField(max_length=200, help_text='Enter name')
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
The User
class is a predefined Django class.
As you can see for Blogger I don't create a class but I use a default one from Django class User
.
In the template blog_list.html
I use the following line to display the blog author with a link to the author page:
blog_list.html
<a href="/blog/blogger/{{ blog.author.id }}">{{blog.author.first_name}} {{blog.author.last_name}}</a>
wiews.py
class BlogListView(generic.ListView):
model = Blog
ordering = ['-date']
paginate_by = 5
class BloggerDetailView(generic.DetailView):
model = User
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('blog/<int:pk>', views.BlogDetailView.as_view(), name='blog-detail'),
path('blogs/', views.BlogListView.as_view(), name='blogs'),
path('blogger/<int:pk>', views.BloggerDetailView.as_view(), name='blogger-detail'),
]
My question is how can I declare an absolute_url
for blog.author
to NOT use the manual constructed /blog/blogger/{{ blog.author.id }}
?
You can make a proxy model [Django-doc], this is not a new (real) model. Behind the curtains, it uses the User
model, but it converts it to Author
objects, and we can add logic to that Author
object:
from django.contrib.auth.models import User
class Author(User):
class Meta:
proxy = True
def get_absolute_url(self):
return reverse('blogger-detail', args=(self.pk,))
and then use that proxy model in the ForeignKey
instead:
class Blog(models.Model):
name = models.CharField(max_length=200, help_text='Enter name')
author = models.ForeignKey(
Author, on_delete=models.CASCADE, null=True, blank=True
)
then in the template, you use:
<a href="{{ blog.author.get_absolute_url }}">link</a>