diff --git a/api.http b/api.http new file mode 100644 index 0000000..a0cf299 --- /dev/null +++ b/api.http @@ -0,0 +1,7 @@ +@baseUrl=http://127.0.0.1:8000/api/v1 + +### +GET {{baseUrl}}/recipes HTTP/1.1 + +### +GET {{baseUrl}}/recipes/76 HTTP/1.1 \ No newline at end of file diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..af7d23d --- /dev/null +++ b/api/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "api" + verbose_name = "REST API" diff --git a/api/migrations/__init__.py b/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/pagination.py b/api/pagination.py new file mode 100644 index 0000000..5a68e22 --- /dev/null +++ b/api/pagination.py @@ -0,0 +1,5 @@ +from rest_framework import pagination + + +class CreatedAtPagination(pagination.CursorPagination): + ordering = "-pk" diff --git a/api/serializers.py b/api/serializers.py new file mode 100644 index 0000000..1caecbf --- /dev/null +++ b/api/serializers.py @@ -0,0 +1,20 @@ +from rest_framework import serializers + +from recipes import models + + +class RecipeSerializer(serializers.ModelSerializer): + class Meta: + model = models.Recipe + fields = ( + "pk", + "name", + "crust", + "description", + "weight", + "thumbnail", + "category", + "program", + "created_at", + "updated_at", + ) diff --git a/api/settings.py b/api/settings.py new file mode 100644 index 0000000..d175847 --- /dev/null +++ b/api/settings.py @@ -0,0 +1,4 @@ +REST_FRAMEWORK = { + "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.CursorPagination", + "PAGE_SIZE": 25, +} diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..a2b3583 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from rest_framework import routers + +from api import views + +router = routers.SimpleRouter(trailing_slash=False) +router.register("recipes", views.RecipesViewSet) + + +urlpatterns = router.urls diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..2cecfad --- /dev/null +++ b/api/views.py @@ -0,0 +1,10 @@ +from rest_framework import generics, viewsets +from api import serializers + +from recipes import repositories + + +# Create your views here. +class RecipesViewSet(viewsets.ReadOnlyModelViewSet): + queryset = repositories.RecipesRepository.select() + serializer_class = serializers.RecipeSerializer diff --git a/bread/settings.py b/bread/settings.py index e8f9f3a..08a663a 100644 --- a/bread/settings.py +++ b/bread/settings.py @@ -54,7 +54,9 @@ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", - "recipes", + "recipes.apps.RecipesConfig", + "api.apps.ApiConfig", + "rest_framework", ] if DEBUG: @@ -198,3 +200,8 @@ # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +REST_FRAMEWORK = { + "DEFAULT_PAGINATION_CLASS": "api.pagination.CreatedAtPagination", + "PAGE_SIZE": 25, +} diff --git a/recipes/apps.py b/recipes/apps.py index 2102d12..f94b054 100644 --- a/recipes/apps.py +++ b/recipes/apps.py @@ -1,7 +1,7 @@ from django.apps import AppConfig -class DefaultConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'recipes' - verbose_name = 'Книга рецептов' +class RecipesConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "recipes" + verbose_name = "Книга рецептов" diff --git a/recipes/repositories.py b/recipes/repositories.py index 450077f..22f1c58 100644 --- a/recipes/repositories.py +++ b/recipes/repositories.py @@ -7,6 +7,10 @@ class RecipesRepository: + @classmethod + def select(cls): + return models.Recipe.objects.all() + @classmethod def get_random(cls) -> typing.Union[models.Recipe, None]: max_id = models.Recipe.objects.aggregate(max_id=djmodels.Max("id"))["max_id"] diff --git a/recipes/urls.py b/recipes/urls.py index 14ba781..22c5eb1 100644 --- a/recipes/urls.py +++ b/recipes/urls.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from django.urls import path +from django.urls import include, path from django.conf import settings from django.conf.urls.static import static from django.views.decorators.cache import cache_page @@ -33,6 +33,7 @@ views.CommentAddView.as_view(), name="comment_add", ), + path("api/v1/", include("api.urls")), ] if settings.DEBUG: diff --git a/requirements.txt b/requirements.txt index 773a0f2..6a788ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,10 @@ +Django==4.1.10 +Pillow==9.4.0 azure-storage-blob==12.13.0 boto3==1.26.24 django-storages==1.12.3 -Django==4.1.10 +djangorestframework==3.14.0 mysqlclient==2.1.1 -Pillow==9.4.0 python-dotenv==0.19.2 requests==2.31.0 whitenoise==6.0.0