From 7a8046f02929af881348fba60efb35cfae9c7e6c Mon Sep 17 00:00:00 2001 From: NCat Date: Sat, 25 Feb 2023 23:51:31 +0500 Subject: [PATCH 1/2] without tests --- Dockerfile | 2 +- docs/source/code.rst | 1 + src/__init__.py | 0 src/author/__init__.py | 0 src/author/admin.py | 24 ++++++++ src/author/apps.py | 7 +++ src/author/migrations/0001_initial.py | 61 +++++++++++++++++++ src/author/migrations/__init__.py | 0 src/author/models.py | 34 +++++++++++ .../templates/author/author_detail.html | 11 ++++ src/author/templates/author/author_list.html | 13 ++++ src/author/tests.py | 3 + src/author/urls.py | 9 +++ src/author/views.py | 14 +++++ src/blog/migrations/0001_initial.py | 16 +++-- ...2_alter_blog_options_alter_blog_content.py | 28 --------- src/jobs/migrations/0001_initial.py | 12 +++- src/jobs/models.py | 13 +++- src/jobs/templates/jobs/job_detail.html | 10 +-- src/jobs/templates/jobs/job_list.html | 2 +- src/jobs/urls.py | 12 ++++ src/jobs/views.py | 6 +- src/manage.py | 1 + src/portfolio/migrations/__init__.py | 0 src/portfolio/settings.py | 1 + src/portfolio/templates/base.html | 7 +-- src/portfolio/urls.py | 11 +++- 27 files changed, 247 insertions(+), 51 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/author/__init__.py create mode 100644 src/author/admin.py create mode 100644 src/author/apps.py create mode 100644 src/author/migrations/0001_initial.py create mode 100644 src/author/migrations/__init__.py create mode 100644 src/author/models.py create mode 100644 src/author/templates/author/author_detail.html create mode 100644 src/author/templates/author/author_list.html create mode 100644 src/author/tests.py create mode 100644 src/author/urls.py create mode 100644 src/author/views.py delete mode 100644 src/blog/migrations/0002_alter_blog_options_alter_blog_content.py create mode 100644 src/jobs/urls.py create mode 100644 src/portfolio/migrations/__init__.py diff --git a/Dockerfile b/Dockerfile index 8176851..11cf538 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,4 +27,4 @@ WORKDIR /src # root is used as a hotfix for package introspection problem # https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000373944/comments/7286554132370 -USER root +USER root \ No newline at end of file diff --git a/docs/source/code.rst b/docs/source/code.rst index 9dc7ee3..58558db 100644 --- a/docs/source/code.rst +++ b/docs/source/code.rst @@ -5,3 +5,4 @@ portfolio jobs blog + author diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 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..d8f70fe --- /dev/null +++ b/src/author/admin.py @@ -0,0 +1,24 @@ +from django.contrib import admin + +# Register your models here. +from django.contrib import admin + +from author.models import Author + + +@admin.register(Author) +class AuthorAdmin(admin.ModelAdmin): + list_display = ( + "resume_url", + "github_url", + "email", + "created_at", + "updated_at", + ) + + search_fields = ("email",) + + list_filter = ( + "created_at", + "updated_at", + ) \ No newline at end of file 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/migrations/0001_initial.py b/src/author/migrations/0001_initial.py new file mode 100644 index 0000000..b00b03c --- /dev/null +++ b/src/author/migrations/0001_initial.py @@ -0,0 +1,61 @@ +# Generated by Django 4.1.7 on 2023-02-25 18:43 + +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="Время обновления записи" + ), + ), + ( + "resume_url", + models.URLField( + help_text="Ссылка на резюме автора", verbose_name="Резюме" + ), + ), + ( + "github_url", + models.URLField( + help_text="Ссылка на гитхаб автора", verbose_name="GitHub" + ), + ), + ( + "email", + models.EmailField( + help_text="Почта автора", 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..0872a7a --- /dev/null +++ b/src/author/models.py @@ -0,0 +1,34 @@ +from django.db import models + +# Create your models here. + +from django.db import models + +from base.models import TimeStampMixin + + +class Author(TimeStampMixin): + """ + Модель для хранения данных об авторе. + """ + resume_url = models.URLField( + verbose_name="Резюме", + help_text="Ссылка на резюме автора", + ) + github_url = models.URLField( + verbose_name="GitHub", + help_text="Ссылка на гитхаб автора", + ) + + email = models.EmailField( + verbose_name="Почта", + help_text="Почта автора", + ) + + + class Meta: + verbose_name = "Данные об авторе" + verbose_name_plural = "Данные об авторе" + + def __str__(self) -> str: + return f'Объект "Автор" (id={self.pk})' diff --git a/src/author/templates/author/author_detail.html b/src/author/templates/author/author_detail.html new file mode 100644 index 0000000..14737b2 --- /dev/null +++ b/src/author/templates/author/author_detail.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} + +{% load static %} + +{% block author_content %} + +{% endblock %} \ No newline at end of file diff --git a/src/author/templates/author/author_list.html b/src/author/templates/author/author_list.html new file mode 100644 index 0000000..f1a803d --- /dev/null +++ b/src/author/templates/author/author_list.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} + +{% load static %} + +{% block author_content %} + {% for author in object_list %} + + {% endfor %} +{% endblock %} diff --git a/src/author/tests.py b/src/author/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/src/author/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/src/author/urls.py b/src/author/urls.py new file mode 100644 index 0000000..40ec90b --- /dev/null +++ b/src/author/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from author.views import AutorListView +from author.views import AutorDetailView + +urlpatterns = [ + path("", AutorListView.as_view(), name="authors"), + path("/", AutorDetailView.as_view(), name="author"), +] \ No newline at end of file diff --git a/src/author/views.py b/src/author/views.py new file mode 100644 index 0000000..4ca9c32 --- /dev/null +++ b/src/author/views.py @@ -0,0 +1,14 @@ +from django.shortcuts import render + +# Create your views here. +from django.views.generic import DetailView, ListView + +from author.models import Author + + +class AuthorListView(ListView): + model = Author + + +class AuthorDetailView(DetailView): + model = Author diff --git a/src/blog/migrations/0001_initial.py b/src/blog/migrations/0001_initial.py index 3f830e8..d385322 100644 --- a/src/blog/migrations/0001_initial.py +++ b/src/blog/migrations/0001_initial.py @@ -1,6 +1,6 @@ -# Generated by Django 4.1.1 on 2022-09-20 15:45 -from typing import List +# Generated by Django 4.1.7 on 2023-02-25 12:45 +import ckeditor_uploader.fields from django.db import migrations, models @@ -8,7 +8,7 @@ class Migration(migrations.Migration): initial = True - dependencies: List = [] + dependencies = [] operations = [ migrations.CreateModel( @@ -36,7 +36,12 @@ class Migration(migrations.Migration): ), ), ("title", models.CharField(max_length=255, verbose_name="Заголовок")), - ("content", models.TextField(verbose_name="Содержимое сообщения")), + ( + "content", + ckeditor_uploader.fields.RichTextUploadingField( + verbose_name="Содержимое сообщения" + ), + ), ( "image", models.ImageField(upload_to="images/", verbose_name="Изображение"), @@ -47,7 +52,8 @@ class Migration(migrations.Migration): ), ], options={ - "abstract": False, + "verbose_name": "Сообщение блога", + "verbose_name_plural": "Сообщения блога", }, ), ] diff --git a/src/blog/migrations/0002_alter_blog_options_alter_blog_content.py b/src/blog/migrations/0002_alter_blog_options_alter_blog_content.py deleted file mode 100644 index aab0535..0000000 --- a/src/blog/migrations/0002_alter_blog_options_alter_blog_content.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 4.1.1 on 2022-09-26 13:57 - -import ckeditor_uploader.fields -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("blog", "0001_initial"), - ] - - operations = [ - migrations.AlterModelOptions( - name="blog", - options={ - "verbose_name": "Сообщение блога", - "verbose_name_plural": "Сообщения блога", - }, - ), - migrations.AlterField( - model_name="blog", - name="content", - field=ckeditor_uploader.fields.RichTextUploadingField( - verbose_name="Содержимое сообщения" - ), - ), - ] diff --git a/src/jobs/migrations/0001_initial.py b/src/jobs/migrations/0001_initial.py index 78f13cc..524bbe8 100644 --- a/src/jobs/migrations/0001_initial.py +++ b/src/jobs/migrations/0001_initial.py @@ -1,6 +1,6 @@ -# Generated by Django 4.1.1 on 2022-09-20 15:45 -from typing import List +# Generated by Django 4.1.7 on 2023-02-25 12:45 +import ckeditor_uploader.fields from django.db import migrations, models @@ -8,7 +8,7 @@ class Migration(migrations.Migration): initial = True - dependencies: List = [] + dependencies = [] operations = [ migrations.CreateModel( @@ -51,6 +51,12 @@ class Migration(migrations.Migration): verbose_name="Описание", ), ), + ( + "content", + ckeditor_uploader.fields.RichTextUploadingField( + verbose_name="Подробное описание" + ), + ), ], options={ "verbose_name": "Выполненная работа", diff --git a/src/jobs/models.py b/src/jobs/models.py index a5525d1..4102d34 100644 --- a/src/jobs/models.py +++ b/src/jobs/models.py @@ -1,7 +1,7 @@ """ Модели для приложения "Jobs" (выполненные работы). """ - +from ckeditor_uploader.fields import RichTextUploadingField from django.db import models from base.models import TimeStampMixin @@ -22,6 +22,10 @@ class Job(TimeStampMixin): verbose_name="Описание", help_text="Краткое описание выполненной работы", ) + content = RichTextUploadingField( + verbose_name="Подробное описание", + + ) class Meta: verbose_name = "Выполненная работа" @@ -29,3 +33,10 @@ class Meta: def __str__(self) -> str: return f'Объект "Выполненная работа" (id={self.pk})' + def summary(self) -> str: + """ + Краткое содержание описания работы. + + :return: + """ + return self.content[:100] + "..." diff --git a/src/jobs/templates/jobs/job_detail.html b/src/jobs/templates/jobs/job_detail.html index 6b40e3f..a6b1911 100644 --- a/src/jobs/templates/jobs/job_detail.html +++ b/src/jobs/templates/jobs/job_detail.html @@ -3,11 +3,11 @@ {% block content %}
-

{{ blog.title }}

-

{{ blog.pub_date }}

-

{{ blog.title }}

-

{{ blog.content }}

- Вернуться в блог +

{{ job.title }}

+

{{ job.pub_date }}

+

{{ job.description }}

+ {{ job.content|safe }} + На главную
{% endblock %} diff --git a/src/jobs/templates/jobs/job_list.html b/src/jobs/templates/jobs/job_list.html index 5765bc2..628b478 100644 --- a/src/jobs/templates/jobs/job_list.html +++ b/src/jobs/templates/jobs/job_list.html @@ -36,7 +36,7 @@

{{ job.description }}

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

diff --git a/src/jobs/urls.py b/src/jobs/urls.py new file mode 100644 index 0000000..2166da3 --- /dev/null +++ b/src/jobs/urls.py @@ -0,0 +1,12 @@ +from django.urls import path + +from jobs.views import IndexJobsListView +from jobs.views import JobDetailView + +urlpatterns = [ + path("", IndexJobsListView.as_view(), name="jobs"), + path("/", JobDetailView.as_view(), name="job"), + # path('/', views.DetailView.as_view(), name='detail'), + # path('/results/', views.ResultsView.as_view(), name='results'), + # path('/vote/', views.vote, name='vote'), +] \ No newline at end of file diff --git a/src/jobs/views.py b/src/jobs/views.py index 17fb444..a1f4330 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 JobDetailView(DetailView): + model = Job diff --git a/src/manage.py b/src/manage.py index e133e89..d575de2 100755 --- a/src/manage.py +++ b/src/manage.py @@ -1,3 +1,4 @@ + #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os diff --git a/src/portfolio/migrations/__init__.py b/src/portfolio/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/portfolio/settings.py b/src/portfolio/settings.py index dbe6dbd..94a6fb5 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", diff --git a/src/portfolio/templates/base.html b/src/portfolio/templates/base.html index 42b2f67..2104ddb 100644 --- a/src/portfolio/templates/base.html +++ b/src/portfolio/templates/base.html @@ -35,11 +35,8 @@

Обо мне

Мои контакты

- + {% block author_content %} + {% endblock %}
diff --git a/src/portfolio/urls.py b/src/portfolio/urls.py index 11ab691..dcec597 100644 --- a/src/portfolio/urls.py +++ b/src/portfolio/urls.py @@ -22,12 +22,21 @@ from django.urls import path, include from jobs.views import IndexJobsListView +from author.views import AuthorListView + from portfolio import settings + + urlpatterns = [ path("admin/", admin.site.urls), path("ckeditor/", include("ckeditor_uploader.urls")), - path("", IndexJobsListView.as_view(), name="home"), + path("", AuthorListView.as_view(), name="authors_content"), + path("", IndexJobsListView.as_view(), name="content"), + path("job/", include("jobs.urls")), path("blog/", include("blog.urls")), + + + ] urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)) From ee84dd46fdfeb244b6234d057a0e7bad2ccdea0e Mon Sep 17 00:00:00 2001 From: NCat Date: Sun, 26 Feb 2023 02:50:09 +0500 Subject: [PATCH 2/2] test and authors --- Makefile | 4 ++-- src/author/admin.py | 4 +--- src/author/models.py | 4 +--- src/author/tests.py | 31 ++++++++++++++++++++++++++- src/author/urls.py | 2 +- src/author/views.py | 2 -- src/jobs/admin.py | 2 +- src/jobs/migrations/0001_initial.py | 2 +- src/jobs/models.py | 2 +- src/jobs/templates/jobs/job_list.html | 3 ++- src/jobs/tests.py | 29 +++++++++++++++++++++++++ src/jobs/urls.py | 2 +- src/manage.py | 1 - src/portfolio/urls.py | 4 ---- 14 files changed, 70 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index ef96780..8bfb7b3 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ lint: # запуск автоматических тестов test: - docker compose run app ./manage.py test + docker compose run app python manage.py test # запуск всех функций поддержки качества кода -all: format lint test +all: format lint test docs-html diff --git a/src/author/admin.py b/src/author/admin.py index d8f70fe..a1fa90a 100644 --- a/src/author/admin.py +++ b/src/author/admin.py @@ -1,5 +1,3 @@ -from django.contrib import admin - # Register your models here. from django.contrib import admin @@ -21,4 +19,4 @@ class AuthorAdmin(admin.ModelAdmin): list_filter = ( "created_at", "updated_at", - ) \ No newline at end of file + ) diff --git a/src/author/models.py b/src/author/models.py index 0872a7a..3ae92a9 100644 --- a/src/author/models.py +++ b/src/author/models.py @@ -1,5 +1,3 @@ -from django.db import models - # Create your models here. from django.db import models @@ -11,6 +9,7 @@ class Author(TimeStampMixin): """ Модель для хранения данных об авторе. """ + resume_url = models.URLField( verbose_name="Резюме", help_text="Ссылка на резюме автора", @@ -25,7 +24,6 @@ class Author(TimeStampMixin): help_text="Почта автора", ) - class Meta: verbose_name = "Данные об авторе" verbose_name_plural = "Данные об авторе" diff --git a/src/author/tests.py b/src/author/tests.py index 7ce503c..a39e78b 100644 --- a/src/author/tests.py +++ b/src/author/tests.py @@ -1,3 +1,32 @@ from django.test import TestCase -# Create your tests here. +from author.models import Author + + +class JobTestCase(TestCase): + """ + Тестирование функций работы + """ + + def setUp(self) -> None: + """ + Настройка перед тестированием. + :return: + """ + + Author.objects.create( + resume_url="https://test.test", + github_url="https://test.test", + email="test@test.test", + ) + + def test_job_messages_creation(self) -> None: + """ + Тестирование моделей работы. + :return: + """ + + author = Author.objects.get(resume_url="https://test.test") + self.assertEqual(author.github_url, "https://test.test") + self.assertEqual(author.email, "test@test.test") + self.assertEqual(str(author), f'Объект "Автор" (id={author.pk})') diff --git a/src/author/urls.py b/src/author/urls.py index 40ec90b..dbc2a52 100644 --- a/src/author/urls.py +++ b/src/author/urls.py @@ -6,4 +6,4 @@ urlpatterns = [ path("", AutorListView.as_view(), name="authors"), path("/", AutorDetailView.as_view(), name="author"), -] \ No newline at end of file +] diff --git a/src/author/views.py b/src/author/views.py index 4ca9c32..650808a 100644 --- a/src/author/views.py +++ b/src/author/views.py @@ -1,5 +1,3 @@ -from django.shortcuts import render - # Create your views here. from django.views.generic import DetailView, ListView diff --git a/src/jobs/admin.py b/src/jobs/admin.py index 2eec2ff..fb4e336 100644 --- a/src/jobs/admin.py +++ b/src/jobs/admin.py @@ -16,7 +16,7 @@ class JobAdmin(admin.ModelAdmin): "updated_at", ) - search_fields = ("description",) + search_fields = ("description", "content") list_filter = ( "created_at", diff --git a/src/jobs/migrations/0001_initial.py b/src/jobs/migrations/0001_initial.py index 524bbe8..9820603 100644 --- a/src/jobs/migrations/0001_initial.py +++ b/src/jobs/migrations/0001_initial.py @@ -8,7 +8,7 @@ class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies: list = [] operations = [ migrations.CreateModel( diff --git a/src/jobs/models.py b/src/jobs/models.py index 4102d34..ee75694 100644 --- a/src/jobs/models.py +++ b/src/jobs/models.py @@ -24,7 +24,6 @@ class Job(TimeStampMixin): ) content = RichTextUploadingField( verbose_name="Подробное описание", - ) class Meta: @@ -33,6 +32,7 @@ class Meta: def __str__(self) -> str: return f'Объект "Выполненная работа" (id={self.pk})' + def summary(self) -> str: """ Краткое содержание описания работы. diff --git a/src/jobs/templates/jobs/job_list.html b/src/jobs/templates/jobs/job_list.html index 628b478..9b69ce6 100644 --- a/src/jobs/templates/jobs/job_list.html +++ b/src/jobs/templates/jobs/job_list.html @@ -34,9 +34,10 @@

{{ 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..b24da08 100644 --- a/src/jobs/tests.py +++ b/src/jobs/tests.py @@ -0,0 +1,29 @@ +from django.test import TestCase + +from jobs.models import Job + + +class JobTestCase(TestCase): + """ + Тестирование функций работы + """ + + def setUp(self) -> None: + """ + Настройка перед тестированием. + :return: + """ + + Job.objects.create(image="test", description="test", content="test" * 100) + + def test_job_messages_creation(self) -> None: + """ + Тестирование моделей работы. + :return: + """ + + job = Job.objects.get(description="test") + + content = "test" * 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 index 2166da3..10af16e 100644 --- a/src/jobs/urls.py +++ b/src/jobs/urls.py @@ -9,4 +9,4 @@ # path('/', views.DetailView.as_view(), name='detail'), # path('/results/', views.ResultsView.as_view(), name='results'), # path('/vote/', views.vote, name='vote'), -] \ No newline at end of file +] diff --git a/src/manage.py b/src/manage.py index d575de2..e133e89 100755 --- a/src/manage.py +++ b/src/manage.py @@ -1,4 +1,3 @@ - #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os diff --git a/src/portfolio/urls.py b/src/portfolio/urls.py index dcec597..398be18 100644 --- a/src/portfolio/urls.py +++ b/src/portfolio/urls.py @@ -27,7 +27,6 @@ from portfolio import settings - urlpatterns = [ path("admin/", admin.site.urls), path("ckeditor/", include("ckeditor_uploader.urls")), @@ -35,8 +34,5 @@ path("", IndexJobsListView.as_view(), name="content"), path("job/", include("jobs.urls")), path("blog/", include("blog.urls")), - - - ] urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))