Alex Kondrashov
Alex Kondrashov

Reputation: 61

How to create unique URLs in django?

My project is type of a blog. In this blog I need to post news. I can just add news with Django admin page and display all the news in one url. Now I want each news to have a unique URL.

My models.py:

from django.db import models

class Newsform(models.Model):
    headline = models.CharField(max_length=50)
    description = models.CharField(max_length=100, default='')
    content = models.CharField(max_length=100, default='')
    image = models.ImageField(upload_to='news_image', blank=True)

views.py:

from django.shortcuts import render
from blog.models import Newsform

def show_content_from_database(request):
    headline_news=Newsform.objects.all()
    context = {
        'headline_news': headline_news
    }
    return render(request, 'blog/index.html', context)

Here is urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.show_content_from_database, 
name='show_content_from_database'),
]

And for the last, the part of index.html, where I display the titles of every news:

{% for headline in headline_news %}
  <h1>{{ headline.headline }}</h1>
{% endfor %}

At best, I'd like to post a unique link to the news here: <h1>{{ headline.headline }}</h1>, and that unique page has to extend some base.html.

I've searched the solution of my problem in the internet, but didn't find. This task may be big enough, so I'd like to see a link to some example in the internet (youtube, or stackoverflow, or github, etc).

Upvotes: 1

Views: 3481

Answers (2)

Transformer
Transformer

Reputation: 3760

since you are coding a blog app, using a slug as your unique identifier is cool. A "slug" is the part of a URL which identifies a page using human-readable keywords, usually based on the title of the page. You can check out this blog article https://keyerror.com/blog/automatically-generating-unique-slugs-in-django

Here is a quick explanation using your available code

Your Models.py

from django.db import models

class Newsform(models.Model):
    headline = models.CharField(max_length=50)
    slug = models.SlugField(unique=True)
    description = models.CharField(max_length=100, default='')
    content = models.CharField(max_length=100, default='')
    image = models.ImageField(upload_to='news_image', blank=True)

Views.py

from django.shortcuts import render, get_object_or_404
from blog.models import Newsform

def show_content_from_database(request, slug):
    headline_news= get_object_or_404(Newsform, slug=slug)
    context = {
        'headline_news': headline_news
    }
    return render(request, 'blog/index.html', context)

Urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<slug:slug>', views.show_content_from_database, 
name='show_content_from_database'),
]

Your Template.html

{% extends 'base.html' %}
    <p>{{ headline_news.headline }}</p>
{% endblock %}

Since you are getting a particular blog page, there is no need for this {% for headline in headline_news %}.

Good Luck!!

Upvotes: 1

Vineeth Sai
Vineeth Sai

Reputation: 3447

In your views.py define a function that would get one object from the primary key it receives.

def show_one_item(request, pk):
    headline_news = Newsform.objects.get(pk=pk) # returns only one object
    context = {
        'headline_news': headline_news
    }
    return render(request, 'blog/new_template.html', context) # Write a new template to view your news.

Add this to your urls.py

urlpatterns = [
    path('', views.show_content_from_database, name='show_content_from_database'), 
    path('news/<pk:pk>', show_one_item, name="show_one_item")
]

And once you write your new_template to fit the function. You have unique urls for each of your news item.

An example of your new_template.html might look like.

{% extends 'base.html' %}
<div class="container">

    <p>{{ headline_news.headline }}</p>
    <p>{{ headline_news.description }}</p>
    <p>{{ headline_news.content }}</p>

</div>

Now, You can go to ../news/1(assuming you didn't mess up django's default behaviour) for viewing your first news item. ../news/2 for second and so on... And later on learn how to do it with slugs to make your urls look realistic.

Upvotes: 1

Related Questions