Normalize article dates and update ArticlePage model to use DateTimeField; configure S3 storage settings and update requirements for django-storages
This commit is contained in:
parent
b04ad110a6
commit
d75ea17b32
46
innovedus_cms/home/migrations/0013_alter_articlepage_date.py
Normal file
46
innovedus_cms/home/migrations/0013_alter_articlepage_date.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Generated by Django 5.2.7 on 2025-11-10 05:37
|
||||
|
||||
import datetime as dt
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
def normalize_article_dates(apps, schema_editor):
|
||||
ArticlePage = apps.get_model("home", "ArticlePage")
|
||||
|
||||
for page in ArticlePage.objects.all():
|
||||
if page.date is None:
|
||||
continue
|
||||
|
||||
value = page.date
|
||||
if isinstance(value, dt.datetime):
|
||||
base = value
|
||||
elif isinstance(value, dt.date):
|
||||
base = dt.datetime.combine(value, dt.time.min)
|
||||
else:
|
||||
continue
|
||||
|
||||
if settings.USE_TZ and timezone.is_naive(base):
|
||||
base = timezone.make_aware(base, timezone.get_default_timezone())
|
||||
|
||||
normalized = base.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
if normalized != page.date:
|
||||
ArticlePage.objects.filter(pk=page.pk).update(date=normalized)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0012_rename_recommended_articlepage_trending_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='articlepage',
|
||||
name='date',
|
||||
field=models.DateTimeField(verbose_name='Published date'),
|
||||
),
|
||||
migrations.RunPython(normalize_article_dates, migrations.RunPython.noop),
|
||||
]
|
||||
@ -35,7 +35,7 @@ class CategoryMixin:
|
||||
"title": category.title,
|
||||
"items": ArticlePage.objects.child_of(category)
|
||||
.live()
|
||||
.order_by("-first_published_at")[:HORIZON_SIZE],
|
||||
.order_by("-date")[:HORIZON_SIZE],
|
||||
"url": category.url,
|
||||
"layout": "horizon",
|
||||
}
|
||||
@ -45,7 +45,7 @@ class CategoryMixin:
|
||||
paginator = Paginator(
|
||||
ArticlePage.objects.child_of(self)
|
||||
.live()
|
||||
.order_by("-first_published_at"),
|
||||
.order_by("-date"),
|
||||
PAGE_SIZE,
|
||||
)
|
||||
page_number = request.GET.get("page") if request else None
|
||||
@ -84,7 +84,7 @@ class CategoryMixin:
|
||||
# No request means no pagination (e.g., homepage)
|
||||
return {
|
||||
"title": latest_page.title,
|
||||
"items": ArticlePage.objects.live().order_by("-first_published_at")[
|
||||
"items": ArticlePage.objects.live().order_by("-date")[
|
||||
:BLOCK_SIZE
|
||||
],
|
||||
"url": latest_page.url,
|
||||
@ -92,7 +92,7 @@ class CategoryMixin:
|
||||
else:
|
||||
# Paginated view
|
||||
paginator = Paginator(
|
||||
ArticlePage.objects.live().order_by("-first_published_at"), PAGE_SIZE
|
||||
ArticlePage.objects.live().order_by("-date"), PAGE_SIZE
|
||||
)
|
||||
page_number = request.GET.get("page")
|
||||
|
||||
@ -111,7 +111,7 @@ class CategoryMixin:
|
||||
def get_trending_articles(self, request=None, exclude_ids=None):
|
||||
trending_page = TrendingPage.objects.first()
|
||||
articles_qs = ArticlePage.objects.filter(trending=True).live().order_by(
|
||||
"-first_published_at"
|
||||
"-date"
|
||||
)
|
||||
|
||||
# Exclude specified article IDs
|
||||
@ -178,7 +178,7 @@ class HomePage(Page, CategoryMixin):
|
||||
"url": category.url,
|
||||
"items": ArticlePage.objects.descendant_of(category)
|
||||
.live()
|
||||
.order_by("-first_published_at")[:HORIZON_SIZE],
|
||||
.order_by("-date")[:HORIZON_SIZE],
|
||||
"layout": "horizon",
|
||||
}
|
||||
)
|
||||
@ -256,7 +256,7 @@ class ArticlePage(Page):
|
||||
related_name="+",
|
||||
help_text="文章內文橫幅圖片",
|
||||
)
|
||||
date = models.DateField("Published date")
|
||||
date = models.DateTimeField("Published date")
|
||||
intro = models.CharField(max_length=250, blank=True)
|
||||
body = StreamField(
|
||||
[
|
||||
@ -292,7 +292,7 @@ class ArticlePage(Page):
|
||||
.exclude(id=self.id)
|
||||
.filter(tags__id__in=tag_ids)
|
||||
.distinct()
|
||||
.order_by("-first_published_at")[:4]
|
||||
.order_by("-date")[:4]
|
||||
)
|
||||
else:
|
||||
related_articles = ArticlePage.objects.none()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB |
@ -170,13 +170,21 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_URL = f'{os.environ.get("AWS_S3_ENDPOINT_URL")}/{os.environ.get("AWS_STORAGE_BUCKET_NAME")}/'
|
||||
|
||||
# Default storage settings
|
||||
# See https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STORAGES
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
|
||||
"OPTIONS": {
|
||||
"endpoint_url": os.environ.get("AWS_S3_ENDPOINT_URL"),
|
||||
"access_key": os.environ.get("AWS_ACCESS_KEY_ID"),
|
||||
"secret_key": os.environ.get("AWS_SECRET_ACCESS_KEY"),
|
||||
"bucket_name": os.environ.get("AWS_STORAGE_BUCKET_NAME"),
|
||||
"region_name": os.environ.get("AWS_S3_REGION_NAME", default="us-east-1"),
|
||||
"addressing_style": "path",
|
||||
},
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
|
||||
@ -4,3 +4,4 @@ gunicorn
|
||||
dj-database-url
|
||||
psycopg[binary]
|
||||
python-dotenv
|
||||
django-storages[boto3]
|
||||
Loading…
x
Reference in New Issue
Block a user