articles
This commit is contained in:
parent
01d35a461b
commit
d1926cfc17
12 changed files with 862 additions and 4 deletions
94
hub/services/models/articles.py
Normal file
94
hub/services/models/articles.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.text import slugify
|
||||
from django.contrib.auth.models import User
|
||||
from django_prose_editor.fields import ProseEditorField
|
||||
from .base import validate_image_size
|
||||
from .services import Service
|
||||
from .providers import CloudProvider, ConsultingPartner
|
||||
|
||||
|
||||
class Article(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
slug = models.SlugField(max_length=250, unique=True)
|
||||
excerpt = models.TextField(
|
||||
max_length=500, help_text="Brief description of the article"
|
||||
)
|
||||
content = ProseEditorField()
|
||||
meta_keywords = models.CharField(
|
||||
max_length=255, blank=True, help_text="SEO keywords separated by commas"
|
||||
)
|
||||
image = models.ImageField(
|
||||
upload_to="article_images/",
|
||||
help_text="Title picture for the article",
|
||||
)
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="articles")
|
||||
|
||||
# Relations to other models
|
||||
related_service = models.ForeignKey(
|
||||
Service,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="articles",
|
||||
help_text="Link this article to a specific service",
|
||||
)
|
||||
related_consulting_partner = models.ForeignKey(
|
||||
ConsultingPartner,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="articles",
|
||||
help_text="Link this article to a consulting partner",
|
||||
)
|
||||
related_cloud_provider = models.ForeignKey(
|
||||
CloudProvider,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="articles",
|
||||
help_text="Link this article to a cloud provider",
|
||||
)
|
||||
|
||||
# Publishing controls
|
||||
is_published = models.BooleanField(
|
||||
default=False, help_text="Only published articles are visible to users"
|
||||
)
|
||||
is_featured = models.BooleanField(
|
||||
default=False, help_text="Featured articles appear prominently in listings"
|
||||
)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
verbose_name = "Article"
|
||||
verbose_name_plural = "Articles"
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Auto-generate slug from title if not provided
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title)
|
||||
counter = 1
|
||||
while Article.objects.filter(slug=self.slug).exists():
|
||||
self.slug = f"{slugify(self.title)}-{counter}"
|
||||
counter += 1
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("services:article_detail", kwargs={"slug": self.slug})
|
||||
|
||||
@property
|
||||
def related_to(self):
|
||||
"""Returns a string describing what this article is related to"""
|
||||
if self.related_service:
|
||||
return f"Service: {self.related_service.name}"
|
||||
elif self.related_consulting_partner:
|
||||
return f"Partner: {self.related_consulting_partner.name}"
|
||||
elif self.related_cloud_provider:
|
||||
return f"Provider: {self.related_cloud_provider.name}"
|
||||
return "General"
|
Loading…
Add table
Add a link
Reference in a new issue