DEV Community

Cover image for How to display Dev To posts on your website blog using Dev To API and Django.
Bonnie
Bonnie

Posted on • Edited on

How to display Dev To posts on your website blog using Dev To API and Django.

Let's assume you own a website or you want to build one and you want to add a blog to it. So you go to Google and google "How to add a blog to your website." After going through the results, you can't find a better option that enables you to add a blog to your site for free or without using WordPress.

A few weeks ago I found myself in this situation and as I went on doing my research, I discovered that you can use dev to API to display articles published there on your website without someone getting redirected to Dev To when they want to read the articles.

My website uses Django for the backend and for that reason, I googled "how to display dev to posts on your website using Django." I went through the results returned by the search but none gave me a solution to the problem I wanted to solve.

After days of trial and error trying to figure out how to do that, I was able to display dev to posts on my website.

Here is how I did it.

Set Up

First things first, make sure you have python installed in your system.

Installing Django

To install Django we will use Pipenv which is used to manage virtual environments. You can install Pipenv to your system using this guide.

Let’s create a new directory and install Django. First, navigate to the Desktop, create a new directory Articles, and enter it with cd.

$ cd ~/Desktop
$ mkdir Articles
$ cd Articles
Enter fullscreen mode Exit fullscreen mode

Now use Pipenv to install Django.

$ pipenv install django
Enter fullscreen mode Exit fullscreen mode

Then create a virtual environment using pipenv shell

$ pipenv shell
Enter fullscreen mode Exit fullscreen mode

You should now see parentheses around the name of your current directory on your command line which indicates the virtual environment is activated.

(Articles) $
Enter fullscreen mode Exit fullscreen mode

Create a new Django project called Blog with the following command. Don’t forget that period . at the end.

(Articles) $ django-admin startproject Blog .
Enter fullscreen mode Exit fullscreen mode

Run the command below and then visit http://127.0.0.1:8000/. You should see Django welcome page.

(Articles) $ python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

Now it’s time to create our Django app. From the command line, quit the server with Control+c. Then use the startapp command followed by the name of our app, which will be posts.

(Articles) $ python manage.py startapp posts
Enter fullscreen mode Exit fullscreen mode

Open the settings.py file and scroll down to INSTALLED_APPS where you’ll see six built-in Django apps already there. Add our new posts app at the bottom:

# Blog/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'posts', # new
]
Enter fullscreen mode Exit fullscreen mode

Models, Views, URLs, Templates

1. Models

First, we will create a model for our project so that we can store the articles fetched by the Dev To API into a database.

Models.py

from django.db import models
import datetime

class Article(models.Model):
    title = models.TextField(blank=True)
    description = models.TextField(blank=True)
    cover_image = models.TextField(blank=True)
    article_body = models.TextField(blank=True)
    published_at = models.DateTimeField(default=datetime.date.today, blank=True, null=True)

    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

Run migrations with the commands below

(Articles) $ python manage.py makemigrations

(Articles) $ python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

To register our model, open admin.py and it should look like this.

Admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('id', 'title')


admin.site.register(Article, ArticleAdmin)
Enter fullscreen mode Exit fullscreen mode

Then create a superuser in order to be able to login to the admin and view data stored in our database.

(Articles) $ python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

2. views

Since we will be making requests to Dev To API, we will need to install requests python library.

$ pipenv install requests
Enter fullscreen mode Exit fullscreen mode

Now visit dev to API website and read about getting an API key together with various API endpoints.

Once on the website, scroll down and on your bottom left select authentification to learn how to get an API key.

Then below authentification, select articles. Scroll down the drop-down menu and select User's published articles.

On your right, you can now see Request samples.

Now this is how your views.py file should look like.

views.py

from django.shortcuts import render
import requests
from .models import Article

def get_articles(request):
   all_articles = {}

   API_KEY = 'Your_API_KEY'

   url = 'https://dev.to/api/articles/me/published'

   headers = {'api-key': API_KEY}

   response = requests.get(url, headers=headers)

   data = response.json()

   for i, item in enumerate (data):
      article_data = Article(
         title = data[i]['title'],
         description = data[i]['description'],
         cover_image = data[i]['cover_image'],
         article_body = data[i]['body_markdown'],
         published_at = data[i]['published_at']
      )

      article_data.save()

      all_articles = Article.objects.all().order_by('-published_at').distinct('published_at')

      return render (request, "blog.html", {"all_articles": all_articles})
Enter fullscreen mode Exit fullscreen mode

In order to display Article Body, we will need to create another view. In this view, we are querying article by id.

def blogBody(request, id):
   article = Article.objects.get(id = id)

   return render (request, "blogBody.html", {"article": article})
Enter fullscreen mode Exit fullscreen mode

Your views.py file should now look like this.

from django.shortcuts import render
import requests
from .models import Article

def get_articles(request):
   all_articles = {}

   API_KEY = 'Your_API_KEY'

   url = 'https://dev.to/api/articles/me/published'

   headers = {'api-key': API_KEY}

   response = requests.get(url, headers=headers)

   data = response.json()

   for i, item in enumerate (data):
      article_data = Article(
         title = data[i]['title'],
         description = data[i]['description'],
         cover_image = data[i]['cover_image'],
         article_body = data[i]['body_markdown'],
         published_at = data[i]['published_at']
      )

      article_data.save()

      all_articles = Article.objects.all().order_by('-published_at').distinct('published_at')

      return render (request, "blog.html", {"all_articles": all_articles})

def blogBody(request, id):
   article = Article.objects.get(id = id)

   return render (request, "blogBody.html", {"article": article})
Enter fullscreen mode Exit fullscreen mode

3. URLs

Now we need to configure our urls. Within the posts app, create a new urls.py file.

urls.py

from django.urls import path
from .views import get_articles, blogBody


urlpatterns = [
    path("blog", blog, name="blog"),
    path("article/<int:id>", blogBody, name="article"),
]
Enter fullscreen mode Exit fullscreen mode

The last step is to update our Blog/urls.py file. It’s common to have multiple apps within a single Django project, like pages here, and they each need their own dedicated URL path.

Update the existing Blog/urls.py file as follows:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("posts.urls"))
]
Enter fullscreen mode Exit fullscreen mode

4. Templates

Create a directory called templates and an HTML file called blog.html and blogBody.html.

(Articles) $ mkdir templates
(Articles) $ touch templates/blog.html
(Articles) $ touch templates/blogBody.html
Enter fullscreen mode Exit fullscreen mode

Next, we need to update Blog/settings.py to tell Django the location of our new templates directory. This is a one-line change to the setting 'DIRS' under TEMPLATES.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #new
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
Enter fullscreen mode Exit fullscreen mode

Our blog.html file should now look like this:

{% for article in get_articles %}
<img src="{{article.cover_image}}" alt="">
<h4>{{article.title}}</h4>
<p>{{article.description}}</p>
<a href="{% url 'article' article.id %}">Read More...</a>
{% endfor %}
Enter fullscreen mode Exit fullscreen mode

Article Body

When we make the API call, the article body is fetched as article markdown. The markdown is received from the API as a string. This means it will look like the raw content you enter on DEV To, rather than the preview/published version (i.e. with all the markdown syntax like ## for headings).

To display it on your website as it appears on DEV To, you'll need to add an extra step to turn the string markdown into HTML. There are a lot of markdown parsing libraries that can do this for you but in this project, we will use a markdown parsing library for Django called Markdown.

To use Markdown we will need to install it into our project.

$ pipenv install markdown
Enter fullscreen mode Exit fullscreen mode

We will create a custom template filter that uses Markdown. Create a templatetags directory within our posts app and then a markdown_extras.py file.

(Articles) $ mkdir posts/templatetags
(Articles) $ touch posts/templatetags/markdown_extras.py
Enter fullscreen mode Exit fullscreen mode

The file itself will import the markdown package and use the fenced code block extension.

# posts/templatetags/markdown_extras.py
from django import template
from django.template.defaultfilters import stringfilter

import markdown as md

register = template.Library()


@register.filter()
@stringfilter
def markdown(value):
    return md.markdown(value, extensions=['markdown.extensions.fenced_code'])
Enter fullscreen mode Exit fullscreen mode

Now we load the custom filter into our template so that content written in Markdown will be outputted as HTML.

Our blogBody.html file should now look like this:

{% load markdown_extras %}

<h4>{{article.title}}</h4>
<img src="{{article.cover_image}}" alt="">
<span>{{article.published_at }}</span>
<p>{{article.article_body | markdown | safe}}</p>
Enter fullscreen mode Exit fullscreen mode

Conclusion

Articles should now appear on your website just like they appear on Dev To.

Hope you find this article helpful. All the best in your coding.

Top comments (3)

Collapse
 
angelotheman profile image
Angel Oduro-Temeng Twumasi

These were some of your earliest works in technical writing. Very simple and straight to the point. Very well done.

Collapse
 
the_greatbonnie profile image
Bonnie

Thanks.

Collapse
 
kurtissfrost profile image
Kurtiss Frost

Now that I have the knowledge on how to do this, I just need to get the skill. I am new to website development and most of the steps in this, sadly went over my head. Maybe one day when I have more knowledge I can implement this. Even though I didn't follow the whole thing, it was still a well written tutorial.