diff --git a/apps/blog/graphql/types.py b/apps/blog/graphql/types.py index 25f38ed..57aa245 100644 --- a/apps/blog/graphql/types.py +++ b/apps/blog/graphql/types.py @@ -18,4 +18,3 @@ class BlogType: slug: strawberry.auto department: strawberry.auto directive: strawberry.auto - work: strawberry.auto diff --git a/apps/blog/migrations/0003_remove_blog_work.py b/apps/blog/migrations/0003_remove_blog_work.py new file mode 100644 index 0000000..27283d9 --- /dev/null +++ b/apps/blog/migrations/0003_remove_blog_work.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.8 on 2025-09-02 06:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0002_alter_blog_department_alter_blog_directive_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='blog', + name='work', + ), + ] diff --git a/apps/blog/models.py b/apps/blog/models.py index 3cfa2f7..5a9fd2b 100644 --- a/apps/blog/models.py +++ b/apps/blog/models.py @@ -7,7 +7,6 @@ from apps.common.models import StatusEnum, UserResource from apps.department.models import Department from apps.strategic.models import StrategicDirectives -from apps.work.models import Work from utils.common import unique_slugify @@ -39,13 +38,6 @@ class Blog(UserResource): blank=True, verbose_name=_("Strategic Directive"), ) - work = models.ForeignKey( - Work, - on_delete=models.SET_NULL, - null=True, - blank=True, - verbose_name=_("Work"), - ) def save(self, *args, **kwargs): if not self.slug: diff --git a/apps/blog/tests/queries_test.py b/apps/blog/tests/queries_test.py index 5d26fc5..76bf078 100644 --- a/apps/blog/tests/queries_test.py +++ b/apps/blog/tests/queries_test.py @@ -29,9 +29,6 @@ class Query: slug status title - work { - pk - } } } """ @@ -64,7 +61,6 @@ def _query(): published_date="2023-01-01", directive=None, cover_image=None, - work=None, ), BlogFactory.create( title="Blog One", @@ -79,7 +75,6 @@ def _query(): published_date="2023-01-01", directive=None, cover_image=None, - work=None, ), ] @@ -100,7 +95,6 @@ def _query(): content=blog.content, directive=None, coverImage=None, - work=None, ) for blog in blog_items ], diff --git a/apps/resources/graphql/filters.py b/apps/resources/graphql/filters.py index 542f221..250b0a7 100644 --- a/apps/resources/graphql/filters.py +++ b/apps/resources/graphql/filters.py @@ -1,7 +1,7 @@ import strawberry import strawberry_django -from apps.resources.models import Resource +from apps.resources.models import Resource, ResourcesType @strawberry_django.filters.filter(Resource, lookups=True) @@ -10,3 +10,4 @@ class ResourceFilter: slug: str | None = strawberry.UNSET id: strawberry.ID | None = strawberry.UNSET directive: strawberry.ID | None = None + type: ResourcesType | None = strawberry.UNSET diff --git a/apps/resources/graphql/types.py b/apps/resources/graphql/types.py index e520e10..6919d88 100644 --- a/apps/resources/graphql/types.py +++ b/apps/resources/graphql/types.py @@ -15,3 +15,4 @@ class ResourceType: directive: strawberry.auto slug: strawberry.auto cover_image: DjangoFileType | None + type: strawberry.auto diff --git a/apps/resources/migrations/0004_resource_type.py b/apps/resources/migrations/0004_resource_type.py new file mode 100644 index 0000000..34d54ec --- /dev/null +++ b/apps/resources/migrations/0004_resource_type.py @@ -0,0 +1,20 @@ +# Generated by Django 5.1.8 on 2025-09-02 08:32 + +import apps.resources.models +import django_choices_field.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('resources', '0003_resource_cover_image'), + ] + + operations = [ + migrations.AddField( + model_name='resource', + name='type', + field=django_choices_field.fields.IntegerChoicesField(choices=[(10, 'Report'), (20, 'Policy And Guidelines')], choices_enum=apps.resources.models.ResourcesType, default=10), + ), + ] diff --git a/apps/resources/models.py b/apps/resources/models.py index ff57c7b..efae3dd 100644 --- a/apps/resources/models.py +++ b/apps/resources/models.py @@ -1,6 +1,7 @@ from django.db import models from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ +from django_choices_field import IntegerChoicesField from mdeditor.fields import MDTextField from apps.common.models import UserResource @@ -8,6 +9,11 @@ from utils.common import unique_slugify +class ResourcesType(models.IntegerChoices): + REPORT = 10, "Report" + POLICY_AND_GUIDELINES = 20, "Policy And Guidelines" + + class Resource(UserResource): title = models.CharField(max_length=255) content = MDTextField(blank=True, null=True) @@ -22,6 +28,7 @@ class Resource(UserResource): ) slug = models.SlugField(unique=True, max_length=250, blank=True, verbose_name=_("Slug")) cover_image = models.ImageField(upload_to="resources/", null=True, blank=True) + type = IntegerChoicesField(choices_enum=ResourcesType, default=ResourcesType.REPORT) def __str__(self): return self.title diff --git a/apps/strategic/admin.py b/apps/strategic/admin.py index e1a537d..ec68a4a 100644 --- a/apps/strategic/admin.py +++ b/apps/strategic/admin.py @@ -10,7 +10,7 @@ class StrategicDirectivesAdmin(UserResourceAdmin): list_display = ("title", "description", "contact_person_name", "contact_person_email") search_fields = ("title", "description", "contact_person_name", "contact_person_email") - list_filter = ("title", "description", "contact_person_name", "contact_person_email") + list_filter = ("title", "contact_person_name", "contact_person_email") ordering = ("title",) readonly_fields = ("slug",) @@ -19,7 +19,7 @@ class StrategicDirectivesAdmin(UserResourceAdmin): class MajorResponsibilitiesAdmin(UserResourceAdmin): list_display = ("title", "description", "directive") search_fields = ("title", "description", "directive__title") - list_filter = ("title", "description", "directive") + list_filter = ("title", "directive") ordering = ("title",) list_select_related = True readonly_fields = ("slug",) diff --git a/apps/strategic/apps.py b/apps/strategic/apps.py index 039b853..4b06408 100644 --- a/apps/strategic/apps.py +++ b/apps/strategic/apps.py @@ -4,3 +4,4 @@ class StrategicConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" name = "apps.strategic" + verbose_name = "Works" diff --git a/apps/strategic/migrations/0003_alter_strategicdirectives_options_and_more.py b/apps/strategic/migrations/0003_alter_strategicdirectives_options_and_more.py new file mode 100644 index 0000000..0dbb877 --- /dev/null +++ b/apps/strategic/migrations/0003_alter_strategicdirectives_options_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.8 on 2025-09-02 06:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('strategic', '0002_strategicdirectives_cover_image'), + ] + + operations = [ + migrations.AlterModelOptions( + name='strategicdirectives', + options={'verbose_name': 'Work', 'verbose_name_plural': 'Works'}, + ), + migrations.AlterField( + model_name='strategicdirectives', + name='description', + field=models.TextField(verbose_name='Description'), + ), + migrations.AlterField( + model_name='strategicdirectives', + name='title', + field=models.CharField(max_length=255, verbose_name='Title'), + ), + ] diff --git a/apps/strategic/models.py b/apps/strategic/models.py index fc5c83c..57b5e56 100644 --- a/apps/strategic/models.py +++ b/apps/strategic/models.py @@ -6,9 +6,10 @@ from utils.common import unique_slugify +# FIXME: rename strategicDirective model name into works class StrategicDirectives(UserResource): - title = models.CharField(max_length=255, verbose_name=_("Strategic Directive Title")) - description = models.TextField(verbose_name=_("Strategic Directive Description")) + title = models.CharField(max_length=255, verbose_name=_("Title")) + description = models.TextField(verbose_name=_("Description")) cover_image = models.ImageField( upload_to="strategic_directives/cover_images", verbose_name=_("Cover Image"), @@ -28,8 +29,8 @@ def save(self, *args, **kwargs): super().save(*args, **kwargs) class Meta: # type: ignore[reportIncompatibleVariableOverride] - verbose_name = _("Strategic Directive") - verbose_name_plural = _("Strategic Directives") + verbose_name = _("Work") + verbose_name_plural = _("Works") class MajorResponsibilities(UserResource): diff --git a/apps/work/admin.py b/apps/work/admin.py index e402c61..e69de29 100644 --- a/apps/work/admin.py +++ b/apps/work/admin.py @@ -1,14 +0,0 @@ -from django.contrib import admin - -from apps.common.admin import UserResourceAdmin - -# Register your models here. -from apps.work.models import Work - - -@admin.register(Work) -class WorkAdmin(UserResourceAdmin): - list_display = ("title", "department", "strategic_directive", "start_date", "end_date") - search_fields = ("title", "department__title", "strategic_directive__title") - list_filter = ["department", "strategic_directive"] - list_select_related = True diff --git a/apps/work/graphql/filters.py b/apps/work/graphql/filters.py deleted file mode 100644 index 507db7a..0000000 --- a/apps/work/graphql/filters.py +++ /dev/null @@ -1,11 +0,0 @@ -import strawberry -import strawberry_django - -from apps.work.models import Work - - -@strawberry_django.filters.filter(Work, lookups=True) -class WorkFilter: - id: strawberry.ID | None = None - department: strawberry.ID | None = None - strategic_directive: strawberry.ID | None = None diff --git a/apps/work/graphql/orders.py b/apps/work/graphql/orders.py deleted file mode 100644 index a343974..0000000 --- a/apps/work/graphql/orders.py +++ /dev/null @@ -1,9 +0,0 @@ -import strawberry -import strawberry_django - -from apps.work.models import Work - - -@strawberry_django.ordering.order(Work) -class WorkOrder: - id: strawberry.auto diff --git a/apps/work/graphql/queries.py b/apps/work/graphql/queries.py deleted file mode 100644 index f09961e..0000000 --- a/apps/work/graphql/queries.py +++ /dev/null @@ -1,15 +0,0 @@ -import strawberry -import strawberry_django - -from .filters import WorkFilter -from .orders import WorkOrder -from .types import WorkType - - -@strawberry.type -class Query: - work: WorkType = strawberry_django.field() - works: list[WorkType] = strawberry_django.field( - order=WorkOrder, - filters=WorkFilter, - ) diff --git a/apps/work/graphql/types.py b/apps/work/graphql/types.py deleted file mode 100644 index 47c3e13..0000000 --- a/apps/work/graphql/types.py +++ /dev/null @@ -1,19 +0,0 @@ -import strawberry -import strawberry_django - -from apps.department.graphql.types import DepartmentType -from apps.strategic.graphql.types import StrategicDirectivesType -from apps.work.models import Work -from utils.graphql.types import DjangoFileType - - -@strawberry_django.type(Work) -class WorkType: - id: strawberry.ID - title: strawberry.auto - description: strawberry.auto - cover_image: DjangoFileType - department: DepartmentType - strategic_directive: StrategicDirectivesType | None - start_date: strawberry.auto - end_date: strawberry.auto diff --git a/apps/work/tests/__init__.py b/apps/work/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/apps/work/tests/queries_test.py b/apps/work/tests/queries_test.py deleted file mode 100644 index 31cc586..0000000 --- a/apps/work/tests/queries_test.py +++ /dev/null @@ -1,100 +0,0 @@ -from apps.department.factories import DepartmentFactory -from apps.strategic.factories import StrategicDirectivesFactory, UserFactory -from apps.work.factories import WorkFactory -from main.tests.base_test import TestCase - - -class TestWorkQuery(TestCase): - class Query: - WORK = """ - query works($order: WorkOrder) { - works(order: $order) { - id - title - description - endDate - id - startDate - strategicDirective { - id - title - } - title - coverImage { - url - } - department { - id - title - } - } - } - """ - - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.user = UserFactory.create(username="nrcs-test") - - def test_work_query(self): - def _query(): - return self.query_check( - self.Query.WORK, - variables={ - "order": {"id": "ASC"}, - }, - ) - - work_items = [ - WorkFactory.create( - title="work one", - description="Something", - cover_image="work1.jpg", - department=DepartmentFactory.create( - title="department one", - ), - strategic_directive=StrategicDirectivesFactory.create( - title="strategic directive one", - ), - start_date="2023-01-01", - end_date="2023-12-31", - ), - WorkFactory.create( - title="work two", - description="Something2", - cover_image="work2.jpg", - department=DepartmentFactory.create( - title="department two", - ), - strategic_directive=StrategicDirectivesFactory.create( - title="strategic directive two", - ), - start_date="2023-01-01", - end_date="2023-12-31", - ), - ] - - content = _query() - assert content["data"] == { - "works": [ - dict( - id=self.gID(work.id), - title=work.title, - coverImage={ - "url": self.get_media_url(work.cover_image.name), - }, - description=work.description, - department={ - "id": self.gID(work.department.id), - "title": work.department.title, - }, - strategicDirective={ - "id": self.gID(work.strategic_directive.id), - "title": work.strategic_directive.title, - }, - startDate=work.start_date, - endDate=work.end_date, - ) - for work in work_items - ], - }, content diff --git a/main/graphql/schema.py b/main/graphql/schema.py index d215be3..4e06a01 100644 --- a/main/graphql/schema.py +++ b/main/graphql/schema.py @@ -15,7 +15,6 @@ from apps.resources.graphql import queries as resources_queries from apps.strategic.graphql import queries as strategic_queries from apps.vacancy.graphql import queries as vacancy_queries -from apps.work.graphql import queries as work_queries from .context import GraphQLContext from .dataloaders import GlobalDataLoader @@ -37,7 +36,6 @@ class Query( department_queries.Query, procurement_queries.Query, vacancy_queries.Query, - work_queries.Query, faq_queries.Query, resources_queries.Query, partner_queries.Query, diff --git a/schema.graphql b/schema.graphql index fbf5584..f09846e 100644 --- a/schema.graphql +++ b/schema.graphql @@ -14,7 +14,7 @@ type AppEnumCollectionDummyEnum { } """ -Blog(id, created_at, modified_at, created_by, modified_by, title, published_date, author, content, cover_image, featured, status, slug, department, directive, work) +Blog(id, created_at, modified_at, created_by, modified_by, title, published_date, author, content, cover_image, featured, status, slug, department, directive) """ input BlogFilter { id: ID @@ -35,7 +35,7 @@ input BlogOrder { } """ -Blog(id, created_at, modified_at, created_by, modified_by, title, published_date, author, content, cover_image, featured, status, slug, department, directive, work) +Blog(id, created_at, modified_at, created_by, modified_by, title, published_date, author, content, cover_image, featured, status, slug, department, directive) """ type BlogType { id: ID! @@ -49,7 +49,6 @@ type BlogType { slug: String! department: DjangoModelType directive: DjangoModelType - work: DjangoModelType } input BoolBaseFilterLookup { @@ -470,8 +469,6 @@ type Query { procurement(id: ID!): ProcurementType! jobVacancies(filters: JobVacancyFilter, order: JobVacancyOrder): [JobVacancyType!]! jobVacancy(id: ID!): JobVacancyType! - work(id: ID!): WorkType! - works(filters: WorkFilter, order: WorkOrder): [WorkType!]! faqs(filters: FaqFilter, order: FaqOrder): [FaqType!]! faq(id: ID!): FaqType! resources(filters: ResourceFilter, order: ResourceOrder): [ResourceType!]! @@ -518,13 +515,14 @@ type RadioProgramType { } """ -Resource(id, created_at, modified_at, created_by, modified_by, title, content, file, published_date, directive, slug, cover_image) +Resource(id, created_at, modified_at, created_by, modified_by, title, content, file, published_date, directive, slug, cover_image, type) """ input ResourceFilter { name: String slug: String id: ID directive: ID = null + type: ResourcesType AND: ResourceFilter OR: ResourceFilter NOT: ResourceFilter @@ -536,7 +534,7 @@ input ResourceOrder { } """ -Resource(id, created_at, modified_at, created_by, modified_by, title, content, file, published_date, directive, slug, cover_image) +Resource(id, created_at, modified_at, created_by, modified_by, title, content, file, published_date, directive, slug, cover_image, type) """ type ResourceType { id: ID! @@ -547,6 +545,12 @@ type ResourceType { directive: DjangoModelType slug: String! coverImage: DjangoFileType + type: ResourcesType! +} + +enum ResourcesType { + REPORT + POLICY_AND_GUIDELINES } enum StatusEnum { @@ -631,35 +635,4 @@ type StrategicDirectivesType { coverImage: DjangoFileType slug: String! majorResponsibilities: [MajorResponsibilitiesType!]! -} - -""" -Work(id, created_at, modified_at, created_by, modified_by, title, description, cover_image, department, strategic_directive, start_date, end_date) -""" -input WorkFilter { - id: ID = null - department: ID = null - strategicDirective: ID = null - AND: WorkFilter - OR: WorkFilter - NOT: WorkFilter - DISTINCT: Boolean -} - -input WorkOrder { - id: Ordering -} - -""" -Work(id, created_at, modified_at, created_by, modified_by, title, description, cover_image, department, strategic_directive, start_date, end_date) -""" -type WorkType { - id: ID! - title: String! - description: String! - coverImage: DjangoFileType! - department: DepartmentType! - strategicDirective: StrategicDirectivesType - startDate: Date - endDate: Date } \ No newline at end of file