How to use PMKIN with Django
This guide walks you through integrating PMKIN into your Django application using GraphQL. All the code for this quick start guide is available in our Django quick start repository on GitHub.
Start by installing the necessary packages for your Django project:
pip install gql requests python-dotenv markdown
gql
is used to make network requests..env
file.Set up your PMKIN API key as an environment variable. Create a .env
file in your project root:
PMKIN_API_KEY=your_api_key_here
Ensure your Django application loads environment variables from the .env
file. In your manage.py and wsgi.py files, add the following at the top:
import os
from dotenv import load_dotenv
load_dotenv()
Create a new file pmkin_client.py in your Django project (e.g., in a services directory):
import os
from gql import Client
from gql.transport.requests import RequestsHTTPTransport
pmkin_api_key = os.getenv('PMKIN_API_KEY')
if not pmkin_api_key:
raise ValueError('PMKIN_API_KEY is not set.')
transport = RequestsHTTPTransport(
url='https://pmkin-delivery.onrender.com/graphql',
headers={
'Authorization': f'Bearer {pmkin_api_key}'
},
verify=True,
retries=3,
)
client = Client(
transport=transport,
fetch_schema_from_transport=True,
)
Create a new Django view to list the documents. In your app's views.py file:
from django.shortcuts import render
from gql import gql
from .pmkin_client import client # Adjust the import path as necessary
GET_DOCUMENTS = gql('''
query GetDocuments {
documents(includeDrafts: false) {
id
metaDescription
slug
title
}
}
''')
def blog_list(request):
try:
response = client.execute(GET_DOCUMENTS)
documents = response['documents']
except Exception as e:
documents = []
# Handle exceptions as needed, e.g., log the error
return render(request, 'blog_list.html', {'documents': documents})
Create a template blog_list.html in your templates directory:
<!DOCTYPE html>
<html>
<head>
<title>Blog Posts</title>
</head>
<body>
<h1>Blog Posts</h1>
{% for doc in documents %}
<article>
<h2><a href="{% url 'blog_detail' slug=doc.slug %}">{{ doc.title }}</a></h2>
<p>{{ doc.metaDescription }}</p>
</article>
{% empty %}
<p>No blog posts available.</p>
{% endfor %}
</body>
</html>
Update your urls.py to include the new view:
from django.urls import path
from . import views
urlpatterns = [
path('blog/', views.blog_list, name='blog_list'),
path('blog/<slug:slug>/', views.blog_detail, name='blog_detail'),
]
Add the blog_detail view to your views.py:
from django.shortcuts import render
from django.http import Http404
from gql import gql
from markdown import markdown
from .pmkin_client import client # Adjust the import path as necessary
GET_DOCUMENT = gql('''
query GetDocument($slug: String!) {
documentBySlug(slug: $slug) {
id
markdown
metaDescription
metaTitle
title
}
}
''')
def blog_detail(request, slug):
variables = {'slug': slug}
try:
response = client.execute(GET_DOCUMENT, variable_values=variables)
document = response.get('documentBySlug')
if not document:
raise Http404('Document not found')
document['html_content'] = markdown(document['markdown'])
except Exception as e:
raise Http404('An error occurred while fetching the document.')
return render(request, 'blog_detail.html', {'document': document})
Create the template blog_detail.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ document.metaTitle|default:document.title }}</title>
<meta name="description" content="{{ document.metaDescription }}">
</head>
<body>
<article>
<h1>{{ document.title }}</h1>
{{ document.html_content|safe }}
</article>
</body>
</html>
To dynamically generate metadata for each blog post, we've included the metaTitle
and metaDescription
fields from the PMKIN API. We use these values in the template to set the page title and meta description.
In the views, we've added basic error handling:
You can customize the error handling to fit your application's needs, such as logging errors or displaying custom error pages.
Following this guide, you've integrated PMKIN with your Django application using GraphQL. You can expand on this by adding features like pagination, categories, or search functionality.
Ensure that your .env
file is included in your .gitignore
to prevent it from being checked into version control. Set environment variables securely in production using your hosting provider's recommended practices.
Consider caching responses or using Django's caching mechanisms to reduce the number of API calls, especially for data that doesn't change frequently.