Skip to content

Commit

Permalink
Merge pull request #196 from 2077-Collective/fix/category-url
Browse files Browse the repository at this point in the history
Fix/category url
  • Loading branch information
losndu authored Dec 9, 2024
2 parents 4111e2b + 7286a89 commit a4ea094
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 5 deletions.
3 changes: 2 additions & 1 deletion server/apps/research/admin/category_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
class CategoryAdmin(admin.ModelAdmin):
"""Admin interface for the Category model."""

list_display = ('name', 'created_at')
list_display = ('name', 'slug', 'created_at')
list_per_page = 25
search_fields = ('name',)
list_filter = ('created_at',)
ordering = ('name',)
readonly_fields = ('slug',)
18 changes: 18 additions & 0 deletions server/apps/research/migrations/0015_category_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.8 on 2024-12-09 11:07

from django.db import migrations, models


class Migration(migrations.Migration):

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

operations = [
migrations.AddField(
model_name='category',
name='slug',
field=models.SlugField(blank=True, max_length=255),
),
]
18 changes: 18 additions & 0 deletions server/apps/research/migrations/0016_alter_category_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.8 on 2024-12-09 11:19

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('research', '0015_category_slug'),
]

operations = [
migrations.AlterField(
model_name='category',
name='slug',
field=models.SlugField(blank=True, max_length=255, unique=True),
),
]
27 changes: 27 additions & 0 deletions server/apps/research/models/category.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
from django.db import models
from apps.common.models import BaseModel
from django.utils.text import slugify
from django.db import transaction

class Category(BaseModel):
"""Model for categories."""
name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True, blank=True)

class Meta:
verbose_name_plural = 'Categories'

def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.generate_slug()
super().save(*args, **kwargs)

def __str__(self):
return self.name

def generate_slug(self):

if not self.name:
raise ValueError("Name is required to generate slug")

base_slug = slugify(self.name)
slug = base_slug
num = 1
with transaction.atomic():
while (
Category.objects.select_for_update()
.filter(slug=slug)
.exclude(id=self.id) # Exclude current instance when updating
.exists()
):
slug = f"{base_slug}-{num}"
num += 1
return slug
3 changes: 2 additions & 1 deletion server/apps/research/serializers/category_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

class CategorySerializer(serializers.ModelSerializer):
"""Serializer for the Category model."""
slug = serializers.SlugField(read_only=True, max_length=255, help_text='URL-friendly version of the category name.')
class Meta:
model = Category
fields = ['id', 'name']
fields = ['id', 'name', 'slug']
8 changes: 5 additions & 3 deletions server/apps/research/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ def retrieve_by_identifier(self, request, identifier=None):
status=status.HTTP_404_NOT_FOUND)

# Custom action to retrieve articles by category
@action(detail=False, methods=['get'], url_path=r'category/(?P<category>[-\w]+)')
def retrieve_by_category(self, request, category=None):
@action(detail=False, methods=['get'], url_path=r'category/(?P<category_slug>[-\w]+)')
def retrieve_by_category(self, request, category_slug=None):
"""Retrieve article list by category."""
try:
instances = Article.objects.filter(categories__name=category)
instances = Article.objects.filter(categories__slug=category_slug)
if not instances.exists():
return Response({'error': 'No articles found for this category'}, status=status.HTTP_404_NOT_FOUND)
serializer = self.get_serializer(instances, many=True)
return Response({'success': True, 'data': serializer.data})
except Exception as e:
Expand Down

0 comments on commit a4ea094

Please sign in to comment.