Skip to content

Commit

Permalink
huge templates rework, CSS+js styling added, and other small fixes (W…
Browse files Browse the repository at this point in the history
…ARN: views test is invalid at the moment
  • Loading branch information
slavikyd committed May 27, 2024
1 parent 36f9c98 commit b24de0b
Show file tree
Hide file tree
Showing 79 changed files with 6,097 additions and 116 deletions.
Binary file added .coverage
Binary file not shown.
8 changes: 4 additions & 4 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ jobs:
run: |
chmod +x tests/test.sh
./tests/test.sh tests.test_models
# - name: Тесты views
# run: |
# chmod +x tests/test.sh
# ./tests/test.sh tests.test_views
- name: Тесты views
run: |
chmod +x tests/test.sh
./tests/test.sh tests.test_views
- name: Тесты api
run: |
chmod +x tests/test.sh
Expand Down
7 changes: 6 additions & 1 deletion dot/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ PG_HOST=127.0.0.1
PG_PORT=5555
PG_USER=slavikyd
PG_PASSWORD=vyd123
PG_DBNAME=postgres
PG_DBNAME=postgres
MINIO_ACCESS_KEY_ID=slavikyd
MINIO_SECRET_ACCESS_KEY=vyd123456
MINIO_STORAGE_BUCKET_NAME=static
MINIO_API=http://localhost:9000
MINIO_CONSISTENCY_CHECK_ON_START=False
Binary file modified dot/__pycache__/settings.cpython-311.pyc
Binary file not shown.
Binary file modified dot/__pycache__/urls.cpython-311.pyc
Binary file not shown.
25 changes: 23 additions & 2 deletions dot/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'storages',
'django_minio_backend',
]

REST_FRAMEWORK = {
Expand Down Expand Up @@ -159,7 +161,26 @@

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
STATICFILES_DIRS=(path.join(BASE_DIR,'templates/static'), )
STATIC_ROOT = 'static/'

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

if DEBUG:
AWS_ACCESS_KEY_ID = getenv('MINIO_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = getenv('MINIO_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = getenv('MINIO_STORAGE_BUCKET_NAME')
AWS_S3_ENDPOINT_URL = getenv('MINIO_API')
AWS_S3_USE_SSL = False

MINIO_ENDPOINT = 'localhost:9000'
MINIO_ACCESS_KEY = getenv('MINIO_ACCESS_KEY_ID')
MINIO_SECRET_KEY = getenv('MINIO_SECRET_ACCESS_KEY')
MINIO_USE_HTTPS = False
MINIO_CONSISTENCY_CHECK_ON_START = True
MINIO_PRIVATE_BUCKETS = []
MINIO_PUBLIC_BUCKETS = [
'static',
]
5 changes: 4 additions & 1 deletion dot/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"""Url parsing module."""
from django.contrib import admin
from django.urls import path, include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('dot_app.urls')),
]
]

urlpatterns += staticfiles_urlpatterns()
Binary file modified dot_app/__pycache__/models.cpython-311.pyc
Binary file not shown.
Binary file added dot_app/__pycache__/models_funcs.cpython-311.pyc
Binary file not shown.
Binary file modified dot_app/__pycache__/urls.cpython-311.pyc
Binary file not shown.
Binary file modified dot_app/__pycache__/views.cpython-311.pyc
Binary file not shown.
33 changes: 33 additions & 0 deletions dot_app/migrations/0008_board_datasheet_board_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 4.2.13 on 2024-05-25 19:16

from django.db import migrations, models
import django_minio_backend.models


class Migration(migrations.Migration):
dependencies = [
("dot_app", "0007_alter_board_created_alter_board_modified_and_more"),
]

operations = [
migrations.AddField(
model_name="board",
name="datasheet",
field=models.FileField(
blank=True,
null=True,
storage=django_minio_backend.models.MinioBackend(bucket_name="static"),
upload_to=django_minio_backend.models.iso_date_prefix,
),
),
migrations.AddField(
model_name="board",
name="image",
field=models.FileField(
blank=True,
null=True,
storage=django_minio_backend.models.MinioBackend(bucket_name="static"),
upload_to=django_minio_backend.models.iso_date_prefix,
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.2.13 on 2024-05-26 17:48

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("dot_app", "0008_board_datasheet_board_image"),
]

operations = [
migrations.AlterModelOptions(
name="board",
options={"ordering": ["-id"]},
),
migrations.AlterModelOptions(
name="manufacturer",
options={"ordering": ["-id"]},
),
migrations.AlterModelOptions(
name="subtype",
options={"ordering": ["-id"]},
),
]
Binary file not shown.
Binary file not shown.
41 changes: 39 additions & 2 deletions dot_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
from django.conf.global_settings import AUTH_USER_MODEL
# from django_currentuser.middleware import (
# get_current_user, get_current_authenticated_user)
from django_minio_backend import MinioBackend, iso_date_prefix
from .models_funcs import create_manager, create_save



def get_datetime():
return datetime.now(timezone.utc)
Expand Down Expand Up @@ -53,6 +56,7 @@ def __str__(self) -> str:

class Meta:
db_table = '"databank"."Manufacturer"'
ordering = ['-id']

class Subtype(UUIDMixin, CreatedMixin, ModifiedMixin):
name = models.TextField(null=False, blank=False)
Expand All @@ -63,22 +67,34 @@ def __str__(self) -> str:

class Meta:
db_table = '"databank"."subtype"'
ordering = ['-id']


class Board(UUIDMixin, CreatedMixin, ModifiedMixin):
title = models.TextField(null=False, blank=False)
description = models.TextField(null=True, blank=True)
type = models.TextField(null=True, blank=True, default='Undefined')
year = models.IntegerField(null=True, blank=True, validators=[check_year,], default=date.today().year)

datasheet = models.FileField(
null=True, blank=True,
storage=MinioBackend(bucket_name='static'),
upload_to=iso_date_prefix,
)
image = models.FileField(
null=True, blank=True,
storage=MinioBackend(bucket_name='static'),
upload_to=iso_date_prefix,
)
subtypes = models.ManyToManyField(Subtype, through='BoardSubtype')
manufacturers = models.ManyToManyField(Manufacturer, through='BoardManufacturer')

def __str__(self) -> str:
return f'{self.title}, {self.year}, {self.type} pages'


class Meta:
db_table = '"databank"."Board"'
ordering = ['-id']

class BoardBoard(UUIDMixin, CreatedMixin):
connection_choices = (
Expand Down Expand Up @@ -112,16 +128,37 @@ class Meta:
('board', 'manufacturer'),
)

client_validators = (
('created', check_created), ('modified', check_modified),
)

class Client(UUIDMixin, CreatedMixin, ModifiedMixin):
user = models.OneToOneField(AUTH_USER_MODEL, verbose_name=('user'), on_delete=models.CASCADE)

user = models.OneToOneField(AUTH_USER_MODEL, unique=True, verbose_name=('user'), on_delete=models.CASCADE)
boards = models.ManyToManyField(Board, through='BoardClient', verbose_name=('boards'))
objects = create_manager(client_validators)
save = create_save(client_validators)

class Meta:
db_table = '"databank"."client"'
verbose_name = ('client')
verbose_name_plural = ('clients')

@property
def username(self) -> str:
return self.user.username

@property
def first_name(self) -> str:
return self.user.first_name

@property
def last_name(self) -> str:
return self.user.last_name

def __str__(self) -> str:
return f'{self.username} ({self.first_name} {self.last_name})'

class BoardClient(UUIDMixin, CreatedMixin):
board = models.ForeignKey(Board, on_delete=models.CASCADE, verbose_name=('board'))
client = models.ForeignKey(Client, on_delete=models.CASCADE, verbose_name=('client'))
Expand Down
22 changes: 22 additions & 0 deletions dot_app/models_funcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django.db import models

def create_manager(validators: tuple[tuple[str, callable]]):
class Manager(models.Manager):
@staticmethod
def check_and_validate(kwargs, value, validator):
if value in kwargs.keys():
validator(kwargs.get(value))

def create(self, **kwargs):
for value, validator in validators:
self.check_and_validate(kwargs, value, validator)
return super().create(**kwargs)
return Manager

def create_save(validators: tuple[tuple[str, callable]]):
def save(self, *args, **kwargs) -> None:
for value, validator in validators:
validator(getattr(self, value))
return super(self.__class__, self).save(*args, **kwargs)

return save
Empty file added dot_app/templates_data.py
Empty file.
3 changes: 0 additions & 3 deletions dot_app/tests.py

This file was deleted.

9 changes: 6 additions & 3 deletions dot_app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BoardViewSet, SubtypeViewSet, ManufacturerViewSet
from django.urls import re_path
from rest_framework import permissions, authentication
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

router = DefaultRouter()
router.register(r'boards', BoardViewSet)
Expand All @@ -32,7 +32,7 @@
path('api/', include(router.urls), name='api'),
path('api-auth/', include('rest_framework.urls'), name='rest_framework'),
path('boards/', views.Board_ListView.as_view(), name='boards'),
path('book/', views.board_view, name='board'),
path('board/', views.board_view, name='board'),
path('manufacturers/', views.Manufacturer_ListView.as_view(), name='manufacturers'),
path('manufacturer/', views.manufacturer_view, name='manufacturer'),
path('register/', views.register, name='register'),
Expand All @@ -42,4 +42,7 @@
path('dot_swagger/', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
path('404/', views.not_found_page, name='404_page'),
path('profile/', views.profile, name='profile')
]
urlpatterns += staticfiles_urlpatterns()
49 changes: 43 additions & 6 deletions dot_app/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Any
from django.shortcuts import render
from django.shortcuts import render, redirect
from django.views.generic import ListView
from django.core.paginator import Paginator
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from rest_framework.viewsets import ModelViewSet
Expand All @@ -26,6 +27,9 @@ def home_page(request):
}
)

def not_found_page(request):
return render(request, '404.html')

def create_list_view(model_class, plural_name, template):
class ModelListView(ListView):
model = model_class
Expand All @@ -48,10 +52,16 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
Subtype_ListView = create_list_view(Subtype, 'subtypes', 'catalog/subtypes.html')

def create_view(model_class, context_name, template):
@login_required
def view(request):
id_ = request.GET.get('id', None)
target = model_class.objects.get(id=id_) if id_ else None
return render(request, template, {context_name: target})
context = {context_name: target}
return render(
request,
template,
context,
)
return view


Expand Down Expand Up @@ -106,21 +116,48 @@ class CustomViewSet(ModelViewSet):

return CustomViewSet

@login_required
def profile(request):
client = Client.objects.get(user=request.user)
client_attrs = ('username', 'first_name', 'last_name', 'money')


client_attrs = 'username', 'first_name', 'last_name'
client_data = {attr: getattr(client, attr) for attr in client_attrs}
form_errors = ''
return render(
request,
'pages/profile.html',
{
'client_data': client_data,
'form_errors': form_errors,
'client_boards': client.boards.all(),
},
}
)

@login_required
def bookmark(request):
client = Client.objects.get(user=request.user)
id_ = request.GET.get('id', None)
if not id_:
return redirect('boards')
try:
board = Board.objects.get(id=id_)
except (ValidationError, ObjectDoesNotExist):
return redirect('boards')
if not board:
return redirect('boards')
if board in client.boards.all():
return redirect('profile')



return render(
request,
'pages/bookmark.html',
{
'board': board,
}
)


@login_required
def user_logout(request):
logout(request)
Expand Down
Loading

0 comments on commit b24de0b

Please sign in to comment.