Add support for pinned pages

This commit is contained in:
Gabriel Augendre 2020-08-17 09:57:24 +02:00
parent 89f29e649a
commit 731a443209
10 changed files with 110 additions and 8 deletions

View file

@ -4,5 +4,4 @@ Simple blog management system.
## Todo
4. Find a nice way to display metadata (author, dates, etc)
5. Allow adding pages (pinned articles ?)
6. Add syntax coloration to code blocks

View file

@ -4,7 +4,7 @@ from django.contrib.admin import register
from django.contrib.auth.admin import UserAdmin
from django.db import models
from .models import Article, User
from .models import Article, Page, User
admin.site.register(User, UserAdmin)
@ -67,3 +67,22 @@ class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {"all": ("admin_articles.css",)}
@register(Page)
class PageAdmin(ArticleAdmin):
list_display = ["position"] + ArticleAdmin.list_display
fieldsets = [
(
"Metadata",
{
"fields": (
("title", "slug", "position"),
("author", "status"),
("published_at", "created_at", "updated_at"),
"views_count",
)
},
),
("Content", {"fields": ("content",)}),
]

View file

@ -0,0 +1,5 @@
from articles.models import Article, Page
def pages(request):
return {"pages": Page.objects.filter(status=Article.PUBLISHED)}

View file

@ -0,0 +1,31 @@
# Generated by Django 3.1 on 2020-08-17 07:00
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("articles", "0005_article_slug"),
]
operations = [
migrations.CreateModel(
name="Page",
fields=[
(
"article_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="articles.article",
),
),
],
bases=("articles.article",),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 3.1 on 2020-08-17 07:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("articles", "0006_page"),
]
operations = [
migrations.AlterModelOptions(
name="page", options={"ordering": ["position", "-published_at"]},
),
migrations.AddField(
model_name="page", name="position", field=models.IntegerField(default=0),
),
]

View file

@ -13,6 +13,11 @@ class User(AbstractUser):
pass
class ArticleManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(page__isnull=True)
class Article(models.Model):
DRAFT = "draft"
PUBLISHED = "published"
@ -30,6 +35,9 @@ class Article(models.Model):
views_count = models.IntegerField(default=0)
slug = models.SlugField(unique=True)
objects = ArticleManager()
with_pages = models.Manager()
class Meta:
ordering = ["-published_at"]
@ -67,7 +75,15 @@ class Article(models.Model):
self.status = self.DRAFT
self.save()
def save(self, *args, **kwargs): # new
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
return super().save(*args, **kwargs)
class Page(Article):
objects = models.Manager()
position = models.IntegerField(default=0)
class Meta:
ordering = ["position", "-published_at"]

View file

@ -11,7 +11,15 @@
<nav>
<a href="{% url 'articles-list' %}">Gab's Notes</a>
{% if user.is_authenticated %}
|
<a href="{% url 'drafts-list' %}">View drafts</a>
<a href="{% url 'admin:index' %}">Admin</a>
{% endif %}
{% if pages %}
|
{% for page in pages %}
<a href="{% url 'article-detail' slug=page.slug %}">{{ page.title }}</a>
{% endfor %}
{% endif %}
</nav>
<div class="content">

View file

@ -23,19 +23,18 @@ class DraftsListView(generic.ListView, LoginRequiredMixin):
model = Article
paginate_by = 15
context_object_name = "articles"
queryset = Article.with_pages.filter(status=Article.DRAFT)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs)
context["title"] = "Drafts"
return context
def get_queryset(self):
return super().get_queryset().filter(status=Article.DRAFT)
class ArticleDetailView(generic.DetailView):
model = Article
context_object_name = "article"
queryset = Article.with_pages.all()
def get_queryset(self):
if self.request.user.is_authenticated:

View file

@ -71,6 +71,7 @@ TEMPLATES = [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"articles.context_processors.pages",
],
},
},

View file

@ -7,10 +7,10 @@ def main():
writefreely_c = writefreely.cursor()
db_c = db.cursor()
writefreely_c.execute(
"SELECT slug, created, updated, view_count, title, content FROM posts;"
"SELECT slug, created, updated, view_count, title, content, pinned_position FROM posts;"
)
for line in writefreely_c.fetchall():
db_c.execute(
ret = db_c.execute(
"INSERT INTO articles_article(title, content, status, published_at, created_at, updated_at, author_id, views_count, slug) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);",
(
line[4],
@ -24,6 +24,11 @@ def main():
line[0],
),
)
if line[6] is not None:
db_c.execute(
"INSERT INTO articles_page(article_ptr_id) VALUES (?);",
(ret.lastrowid,),
)
db.commit()