Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(feat): optimise relatedArticles logic #208

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion server/apps/research/admin/article_admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,40 @@
from django.contrib import admin
from django import forms
from apps.research.models import Article, ArticleSlugHistory
from apps.research.models import Article, ArticleSlugHistory, RelatedArticle
from tinymce.widgets import TinyMCE
from .slug_history import current_slug_history



class RelatedArticleInline(admin.TabularInline):
model = RelatedArticle
fk_name = 'from_article'
extra = 1
max_num = 3
verbose_name = 'Related Article'
verbose_name_plural = 'Related Articles'

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'to_article':
# Get the parent object (Article) from the request
obj_id = request.resolver_match.kwargs.get('object_id')
# For new articles (when obj_id is None), show all ready articles
base_queryset = Article.objects.filter(status='ready')

if obj_id:
try:
parent_obj = Article.objects.get(pk=obj_id)
# Exclude self-reference and articles that already have a relationship
base_queryset = base_queryset.exclude(
id=parent_obj.id
).exclude(
related_from__to_article=parent_obj
)
except Article.DoesNotExist:
pass

kwargs['queryset'] = base_queryset
return super().formfield_for_foreignkey(db_field, request, **kwargs)
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
Expand All @@ -19,10 +48,26 @@ def __init__(self, *args, **kwargs):
class ArticleAdmin(admin.ModelAdmin):
"""Admin interface for the Article model."""
form = ArticleForm
inlines = [RelatedArticleInline]

def current_slug_history(self, obj):
return current_slug_history(obj)
current_slug_history.short_description = 'Slug Change History'

def get_inlines(self, request, obj):
# Allow inlines for both new and existing articles
return [RelatedArticleInline]

def save_related(self, request, form, formsets, change):
"""Handle saving related articles for both new and existing articles."""
super().save_related(request, form, formsets, change)

# Process related articles from inline formsets
for formset in formsets:
if isinstance(formset, RelatedArticleInline):
# The related articles will be saved automatically through the formset
pass

fieldsets = [
('Article Details', {'fields': ['title', 'slug', 'authors', 'acknowledgement', 'categories', 'thumb', 'content', 'summary', 'status', 'scheduled_publish_time']}),
('Sponsorship Details', {'fields': ['is_sponsored', 'sponsor_color', 'sponsor_text_color']}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 5.0.8 on 2024-12-12 04:31

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('research', '0014_alter_article_authors'),
]

operations = [
migrations.CreateModel(
name='RelatedArticle',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('from_article', models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name='related_from',
to='research.article',
)),
('to_article', models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name='related_to',
to='research.article',
)),
],
),
migrations.AddField(
model_name='article',
name='related_articles',
field=models.ManyToManyField(
blank=True,
related_name='referenced_by',
through='research.RelatedArticle',
to='research.article',
),
),
migrations.AddConstraint(
model_name='relatedarticle',
constraint=models.CheckConstraint(
check=~models.Q(from_article=models.F('to_article')),
name='prevent_self_reference',
),
),
migrations.AlterUniqueTogether(
name='relatedarticle',
unique_together={('from_article', 'to_article')},
),
]
2 changes: 1 addition & 1 deletion server/apps/research/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .category import Category
from .author import Author
from .article import Article, ArticleSlugHistory
from .article import Article, ArticleSlugHistory, RelatedArticle
Loading
Loading