From 731a443209647d2fadef6203f317576caf441674 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 17 Aug 2020 09:57:24 +0200 Subject: [PATCH] Add support for pinned pages --- README.md | 1 - articles/admin.py | 21 ++++++++++++- articles/context_processors.py | 5 +++ articles/migrations/0006_page.py | 31 +++++++++++++++++++ .../migrations/0007_auto_20200817_0941.py | 19 ++++++++++++ articles/models.py | 18 ++++++++++- articles/templates/articles/base.html | 8 +++++ articles/views/html.py | 5 ++- blog/settings.py | 1 + migration.py | 9 ++++-- 10 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 articles/context_processors.py create mode 100644 articles/migrations/0006_page.py create mode 100644 articles/migrations/0007_auto_20200817_0941.py diff --git a/README.md b/README.md index 7d062f9..e0418e4 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/articles/admin.py b/articles/admin.py index dca6518..78de714 100644 --- a/articles/admin.py +++ b/articles/admin.py @@ -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",)}), + ] diff --git a/articles/context_processors.py b/articles/context_processors.py new file mode 100644 index 0000000..410ccf8 --- /dev/null +++ b/articles/context_processors.py @@ -0,0 +1,5 @@ +from articles.models import Article, Page + + +def pages(request): + return {"pages": Page.objects.filter(status=Article.PUBLISHED)} diff --git a/articles/migrations/0006_page.py b/articles/migrations/0006_page.py new file mode 100644 index 0000000..81d5fe9 --- /dev/null +++ b/articles/migrations/0006_page.py @@ -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",), + ), + ] diff --git a/articles/migrations/0007_auto_20200817_0941.py b/articles/migrations/0007_auto_20200817_0941.py new file mode 100644 index 0000000..3699b39 --- /dev/null +++ b/articles/migrations/0007_auto_20200817_0941.py @@ -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), + ), + ] diff --git a/articles/models.py b/articles/models.py index a4d9f78..cec1bb9 100644 --- a/articles/models.py +++ b/articles/models.py @@ -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"] diff --git a/articles/templates/articles/base.html b/articles/templates/articles/base.html index 1ba0712..4539791 100644 --- a/articles/templates/articles/base.html +++ b/articles/templates/articles/base.html @@ -11,7 +11,15 @@
diff --git a/articles/views/html.py b/articles/views/html.py index a623704..e32a706 100644 --- a/articles/views/html.py +++ b/articles/views/html.py @@ -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: diff --git a/blog/settings.py b/blog/settings.py index 7385a6b..640c05c 100644 --- a/blog/settings.py +++ b/blog/settings.py @@ -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", ], }, }, diff --git a/migration.py b/migration.py index b716f61..c3ac02d 100644 --- a/migration.py +++ b/migration.py @@ -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()