diff --git a/src/author/__init__.py b/src/author/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/author/admin.py b/src/author/admin.py new file mode 100644 index 0000000..c22d7bd --- /dev/null +++ b/src/author/admin.py @@ -0,0 +1,24 @@ +""" +Функции панели управления для приложения "Автор". +""" + +from django.contrib import admin +from author.models import Author + + +@admin.register(Author) +class AuthorAdmin(admin.ModelAdmin): + list_display = ( + "cv_link", + "github_link", + "email", + "created_at", + "updated_at", + ) + + search_fields = ("email", "github_link") + + list_filter = ( + "created_at", + "updated_at", + ) diff --git a/src/author/apps.py b/src/author/apps.py new file mode 100644 index 0000000..ed859f9 --- /dev/null +++ b/src/author/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class AuthorConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "author" + verbose_name = "Автор" diff --git a/src/author/context_processors.py b/src/author/context_processors.py new file mode 100644 index 0000000..989d912 --- /dev/null +++ b/src/author/context_processors.py @@ -0,0 +1,9 @@ +from django.http import HttpRequest +from author.models import Author + + +def author(request: HttpRequest) -> dict: + """ + Контекстный процессор для информации об авторе + """ + return {"author": Author.objects.last()} diff --git a/src/author/migrations/0001_initial.py b/src/author/migrations/0001_initial.py new file mode 100644 index 0000000..1ddf666 --- /dev/null +++ b/src/author/migrations/0001_initial.py @@ -0,0 +1,49 @@ +# Generated by Django 4.1.13 on 2024-03-16 14:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Author", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, verbose_name="Время создания записи" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, verbose_name="Время обновления записи" + ), + ), + ("cv_link", models.URLField(verbose_name="Ссылка на резюме")), + ("github_link", models.URLField(verbose_name="Ссылка на GitHub")), + ( + "email", + models.EmailField(max_length=254, verbose_name="Почтовый адрес"), + ), + ], + options={ + "verbose_name": "Автор", + "verbose_name_plural": "Авторы", + }, + ), + ] diff --git a/src/author/migrations/__init__.py b/src/author/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/author/models.py b/src/author/models.py new file mode 100644 index 0000000..3fe5fc3 --- /dev/null +++ b/src/author/models.py @@ -0,0 +1,19 @@ +from django.db import models +from base.models import TimeStampMixin + + +class Author(TimeStampMixin): + """ + Модель для хранения информации об авторе. + """ + + cv_link = models.URLField(verbose_name="Ссылка на резюме") + github_link = models.URLField(verbose_name="Ссылка на GitHub") + email = models.EmailField(verbose_name="Почтовый адрес") + + class Meta: + verbose_name = "Автор" + verbose_name_plural = "Авторы" + + def __str__(self) -> str: + return f'Объект "автор" (id={self.pk})' diff --git a/src/author/tests.py b/src/author/tests.py new file mode 100644 index 0000000..a39b155 --- /dev/null +++ b/src/author/tests.py @@ -0,0 +1 @@ +# Create your tests here. diff --git a/src/author/views.py b/src/author/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/src/author/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/src/jobs/migrations/0002_job_full_description.py b/src/jobs/migrations/0002_job_full_description.py new file mode 100644 index 0000000..ae1d37f --- /dev/null +++ b/src/jobs/migrations/0002_job_full_description.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.13 on 2024-03-16 11:05 + +import ckeditor_uploader.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("jobs", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="job", + name="full_description", + field=ckeditor_uploader.fields.RichTextUploadingField( + default="Подробное описание", + help_text="Подробное описание выполненной работы", + verbose_name="Подробное описание работы", + ), + ), + ] diff --git a/src/jobs/models.py b/src/jobs/models.py index a5525d1..6046114 100644 --- a/src/jobs/models.py +++ b/src/jobs/models.py @@ -4,6 +4,7 @@ from django.db import models +from ckeditor_uploader.fields import RichTextUploadingField from base.models import TimeStampMixin @@ -22,6 +23,11 @@ class Job(TimeStampMixin): verbose_name="Описание", help_text="Краткое описание выполненной работы", ) + full_description = RichTextUploadingField( + verbose_name="Подробное описание работы", + help_text="Подробное описание выполненной работы", + default="Подробное описание", + ) class Meta: verbose_name = "Выполненная работа" @@ -29,3 +35,12 @@ class Meta: def __str__(self) -> str: return f'Объект "Выполненная работа" (id={self.pk})' + + def summary(self) -> str: + """ + Краткое содержание выполненной работы. + + :return: + """ + + return self.full_description[:100] + "..." diff --git a/src/jobs/templates/jobs/job_detail.html b/src/jobs/templates/jobs/job_detail.html index 6b40e3f..60038df 100644 --- a/src/jobs/templates/jobs/job_detail.html +++ b/src/jobs/templates/jobs/job_detail.html @@ -3,10 +3,10 @@ {% block content %}
-

{{ blog.title }}

-

{{ blog.pub_date }}

-

{{ blog.title }}

-

{{ blog.content }}

+

{{ job.description }}

+

{{ job.pub_date }}

+

{{ job.description }}

+

{{ job.full_description|safe }}

Вернуться в блог
diff --git a/src/jobs/templates/jobs/job_list.html b/src/jobs/templates/jobs/job_list.html index 5765bc2..86b43a4 100644 --- a/src/jobs/templates/jobs/job_list.html +++ b/src/jobs/templates/jobs/job_list.html @@ -8,9 +8,9 @@

Привет!

-

Меня зовут Иван Иванов.
Я профессионально занимаюсь разработкой на Python.

+

Меня зовут Данил.
Я профессионально занимаюсь разработкой на Python.

- Иван Иванов + Данил

Написать мне @@ -33,10 +33,12 @@ alt="job image"/>

-

{{ job.description }}

+

{{ job.description }}

+

{{ job.summary|safe }}

{{ job.created_at|date:"d E Y" }}

diff --git a/src/jobs/tests.py b/src/jobs/tests.py index e69de29..adfe3ec 100644 --- a/src/jobs/tests.py +++ b/src/jobs/tests.py @@ -0,0 +1,35 @@ +from django.test import TestCase + +from jobs.models import Job + + +class JobTestCase(TestCase): + """ + Тестирование функций выполненных работ. + """ + + def setUp(self) -> None: + """ + Настройка перед тестированием. + + :return: + """ + + Job.objects.create( + image="Job №1 image path", + description="Job №1 description", + full_description="Job №1 full description. " * 100, + ) + + def test_job_creation(self) -> None: + """ + Тестирование моделей сообщений для выполненной работы. + + :return: + """ + + job = Job.objects.get(description="Job №1 description") + + content = "Job №1 full description. " * 100 + self.assertEqual(job.summary(), content[:100] + "...") + self.assertEqual(str(job), f'Объект "Выполненная работа" (id={job.pk})') diff --git a/src/jobs/urls.py b/src/jobs/urls.py new file mode 100644 index 0000000..c6236aa --- /dev/null +++ b/src/jobs/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from jobs.views import IndexJobsDetailView + +urlpatterns = [ + path("/", IndexJobsDetailView.as_view(), name="job"), +] diff --git a/src/jobs/views.py b/src/jobs/views.py index 17fb444..b286463 100644 --- a/src/jobs/views.py +++ b/src/jobs/views.py @@ -1,7 +1,11 @@ -from django.views.generic import ListView +from django.views.generic import ListView, DetailView from jobs.models import Job class IndexJobsListView(ListView): model = Job + + +class IndexJobsDetailView(DetailView): + model = Job diff --git a/src/portfolio/settings.py b/src/portfolio/settings.py index dbe6dbd..8d8d16a 100644 --- a/src/portfolio/settings.py +++ b/src/portfolio/settings.py @@ -45,6 +45,7 @@ # созданные приложения "jobs.apps.JobsConfig", "blog.apps.BlogConfig", + "author.apps.AuthorConfig", # установленные приложения "ckeditor", "ckeditor_uploader", @@ -73,6 +74,7 @@ "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", + "author.context_processors.author", ], }, }, diff --git a/src/portfolio/templates/base.html b/src/portfolio/templates/base.html index 42b2f67..a9838c6 100644 --- a/src/portfolio/templates/base.html +++ b/src/portfolio/templates/base.html @@ -36,9 +36,9 @@

Обо мне

Мои контакты

diff --git a/src/portfolio/urls.py b/src/portfolio/urls.py index 11ab691..475e2ca 100644 --- a/src/portfolio/urls.py +++ b/src/portfolio/urls.py @@ -29,5 +29,6 @@ path("ckeditor/", include("ckeditor_uploader.urls")), path("", IndexJobsListView.as_view(), name="home"), path("blog/", include("blog.urls")), + path("jobs/", include("jobs.urls")), ] urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))