Content
Coding up Your Initial Markdown Site
Now that you have created an initial working project and app, it's time to add the contents that will allow you to work with and display markdown content in Django. This lecture will walk you through what to change and add, while the next few lectures will explain what we did and why.
Django Relationships
What are Models?
- Starting point for adding new functionality
- Define the essential structure of your database
- ...but declared in a "Pythonic" way using classes, inheritance, etc
- Best of both worlds?
Adding our First Models
We will now update the models file, adding two new model types: Tags and Posts. Open up homepage/blog/models.py. It should look something like this:
from django.db import models
Replace that text with the following:
from django.db import models
from django.urls import reverse
from django.conf import settings
from django.contrib.auth.models import User
class Tag(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return str(self.name)
class Post(models.Model):
title = models.CharField(max_length=200,unique=True)
author = models.ForeignKey(User, null=True, on_delete= models.SET_NULL)
tags = models.ManyToManyField(Tag,blank=True)
content = models.TextField(blank=True,null=True)
class Meta:
ordering = ["title"]
def __str__(self):
return str(self.title)
def get_absolute_url(self):
return reverse('post', args=[str(self.pk)])
Adding administration
go to homepage/blog/admin.py and replace the existing text with the following:
from django.contrib import admin
from django.http import HttpResponseRedirect
from django.urls import path
from django.conf import settings
from .models import Post
from .models import Tag
class TagAdmin(admin.ModelAdmin):
list_display = ['name']
admin.site.register(Tag,TagAdmin)
class PostAdmin(admin.ModelAdmin):
pass
admin.site.register(Post, PostAdmin)
Implementing render functionality in views.py
So let's go to homepage/blog/views.py and replace the text with:
from django.views import generic
from .models import Post
from django.template.response import TemplateResponse
def index(request, *args, **kwargs):
context = {}
return TemplateResponse(request, "index.html", context)
class PostListView(generic.ListView):
model = Post
ordering = ["title"]
# template_name = "blog/post_list.html"
class PostDetailView(generic.DetailView):
model = Post
# template_name = "blog/post_detail.html"
Implementing url mappings
Our next task will be to connect the data and rendering functionality contained in our post model and tag model to the ways we will be interacting with that data through the external website and the admin site.
First, let's go to homepage/blog/urls.py and look at the few lines that were already there.
Replace that with the following:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('posts/', views.PostListView.as_view(), name='posts'),
path('post/<int:pk>', views.PostDetailView.as_view(), name='post'),
]
Adding templates
We need to add a link to our new list of posts
to homepage/blog/templates/base_generic.html add the following line right below the line with <body> in it (and above <main class="container">)
<a href="{% url 'posts' %}">Posts</a>
Create the folder homepage/blog/templates/blog/ as well as a child file homepage/blog/templates/blog/post_list.html and paste in:
{% extends "base_generic.html" %}
{% block content %}
<h1>Posts</h1>
{% if post_list %}
<ul>
{% for post in post_list %}
<li><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>There are no posts in the blog.</p>
{% endif %}
{% endblock %}
Create homepage/blog/templates/blog/post_detail.html and paste in:
{% extends "base_generic.html" %}
{% block title %}
{% if post.title %}
<title>{{post.title}} | DanAukes.com</title>
{% else %}
<title>DanAukes.com</title>
{% endif %}
{% endblock %}
{% block content %}
<article>
<h1>{{post.title}}</h1>
<hr/>
<div class="markdown">
{{ post.content | safe}}
</div>
</article>
{% endblock %}
Helper Commands
Next we're going to define a couple scripts that help us. In the terminal, navigate to the homepage/ directory and create a new file called startup (no file extension).
cd homepage
nano startup
Paste in the following (including the first, commented out line), then save and close your file editor:
#!/usr/bin/bash
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py migrate --run-syncdb
python manage.py createsuperuser
Back in the terminal, make the script executable:
chmod +x startup
Repeat the same for a new file named migrate, pasting in the following code:
#!/usr/bin/bash
python3 manage.py makemigrations
python3 manage.py migrate
don't forget to add executible permission:
chmod +x migrate
Finally, repeat the same for a new filenamed run, pasting in the following code:
#!/usr/bin/bash
python3 manage.py runserver 0.0.0.0:8000
don't forget to add executible permission:
chmod +x run
With those three files you can initialize your database, migrate, and then run your server. from terminal, navigate to homepage and then run the startup script
cd homepage
./startup
Follow the directions to create an initial superuser, or website administrator. With your databases initialized, you can run Django's test server:
./run
Finally, navigate to your website, which will be located at http://localhost:8000. You should see:
Clicking on the posts link should get you to:

