added search endpoint, product models

This commit is contained in:
Alexander Karpov 2022-10-21 21:39:04 +03:00
parent 827c56871b
commit ff57304ba2
21 changed files with 172 additions and 13 deletions

3
.env.example Normal file
View File

@ -0,0 +1,3 @@
DJANGO_DEBUG=yes
DATABASE_URL=postgres://postgres:debug@127.0.0.1:5432/tenderhack
CELERY_BROKER_URL=redis://localhost:6379/0

View File

@ -1 +1,7 @@
urlpatterns = [] from django.urls import path
from search.api.views import SearchApi
urlpatterns = [
path("search", SearchApi.as_view(), name="search_api")
]

View File

@ -1,8 +1,6 @@
""" """
ASGI config for conf project. ASGI config for conf project.
It exposes the ASGI callable as a module-level variable named ``application``. It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
""" """

View File

@ -31,7 +31,7 @@ USE_L10N = True
# https://docs.djangoproject.com/en/dev/ref/settings/#use-tz # https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True USE_TZ = True
# https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths # https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths
LOCALE_PATHS = [str(ROOT_DIR / "locale")] LOCALE_PATHS = [str(APPS_DIR / "locale")]
# DATABASES # DATABASES
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -44,7 +44,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# URLS # URLS
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf # https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
ROOT_URLCONF = "app.conf.urls" ROOT_URLCONF = "conf.urls"
# https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application # https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
WSGI_APPLICATION = "conf.wsgi.application" WSGI_APPLICATION = "conf.wsgi.application"
@ -63,7 +63,7 @@ DJANGO_APPS = [
] ]
THIRD_PARTY_APPS = ["rest_framework", "corsheaders", "drf_yasg"] THIRD_PARTY_APPS = ["rest_framework", "corsheaders", "drf_yasg"]
LOCAL_APPS = [] LOCAL_APPS = ["search"]
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
@ -200,8 +200,6 @@ CELERY_RESULT_SERIALIZER = "json"
CELERY_TASK_TIME_LIMIT = 5 * 60 CELERY_TASK_TIME_LIMIT = 5 * 60
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-soft-time-limit # https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-soft-time-limit
CELERY_TASK_SOFT_TIME_LIMIT = 60 CELERY_TASK_SOFT_TIME_LIMIT = 60
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-scheduler
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
# django-rest-framework # django-rest-framework

View File

@ -1,5 +1,4 @@
from .base import * from .base import *
from .base import env
# GENERAL # GENERAL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -11,7 +10,7 @@ SECRET_KEY = env(
default="7IFkV9gOD8gP3RbPfBuFmcUE4rPVvlnTlVScHr8OBCmHQrA1OIl2la2TJqKIBkTu", default="7IFkV9gOD8gP3RbPfBuFmcUE4rPVvlnTlVScHr8OBCmHQrA1OIl2la2TJqKIBkTu",
) )
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ["", "127.0.0.1"] ALLOWED_HOSTS = ["*", "127.0.0.1"]
# CACHES # CACHES
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -1,8 +1,6 @@
""" """
WSGI config for conf project. WSGI config for conf project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
""" """

View File

@ -6,7 +6,7 @@ import sys
def main(): def main():
"""Run administrative tasks.""" """Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conf.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "conf.settings.local")
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:

3
app/search/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

View File

@ -0,0 +1,21 @@
from rest_framework import serializers
class SearchSerializer(serializers.Serializer):
body = serializers.CharField(max_length=200)
def create(self, validated_data):
raise NotImplemented
def update(self, instance, validated_data):
raise NotImplemented
class ResponseSerializer(serializers.Serializer):
results = serializers.JSONField()
def create(self, validated_data):
raise NotImplemented
def update(self, instance, validated_data):
raise NotImplemented

20
app/search/api/views.py Normal file
View File

@ -0,0 +1,20 @@
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from search.api.serializers import SearchSerializer, ResponseSerializer
from search.services.search import process_string
user_response = openapi.Response("search results", ResponseSerializer)
class SearchApi(APIView):
@swagger_auto_schema(request_body=SearchSerializer, responses={200: user_response})
def post(self, request, format=None):
serializer = SearchSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
return Response(
process_string(serializer.data["body"]), status=status.HTTP_200_OK
)

6
app/search/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SearchConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "search"

View File

@ -0,0 +1,68 @@
# Generated by Django 4.1.2 on 2022-10-21 18:38
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Category",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"name",
models.CharField(max_length=250, unique=True, verbose_name="Имя"),
),
],
options={
"db_table": "Category",
},
),
migrations.CreateModel(
name="Product",
fields=[
(
"id",
models.IntegerField(
db_index=True,
primary_key=True,
serialize=False,
unique=True,
verbose_name="ID CTE",
),
),
(
"name",
models.CharField(
max_length=250, unique=True, verbose_name="Название CTE"
),
),
("characteristic", models.JSONField(verbose_name="Характеристики")),
(
"category",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="products",
to="search.category",
),
),
],
options={
"db_table": "Product",
},
),
]

View File

30
app/search/models.py Normal file
View File

@ -0,0 +1,30 @@
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField("Имя", unique=True, blank=False, max_length=250)
def __str__(self):
return self.name
class Meta:
db_table = "Category"
class Product(models.Model):
id = models.IntegerField(
"ID CTE", primary_key=True, unique=True, blank=False, null=False, db_index=True
)
name = models.CharField("Название CTE", unique=True, blank=False, max_length=250)
category = models.ForeignKey(
Category, related_name="products", on_delete=models.CASCADE
)
characteristic = models.JSONField("Характеристики")
def __str__(self):
return self.name
class Meta:
db_table = "Product"

View File

View File

@ -0,0 +1,2 @@
def process_string(text: str) -> dict:
return {}

3
app/search/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
app/search/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -3,6 +3,7 @@ Django==4.0.8
django-cors-headers==3.13.0 django-cors-headers==3.13.0
django-environ==0.9.0 django-environ==0.9.0
"drf-yasg[validation]" "drf-yasg[validation]"
typing-extensions
Pillow==9.2.0 Pillow==9.2.0
redis==4.3.4 redis==4.3.4