reformed project

This commit is contained in:
Alexander Karpov 2023-01-11 13:43:12 +03:00
parent e9e7f05e43
commit 2952345ace
12 changed files with 344 additions and 102 deletions

View File

@ -1,12 +1,13 @@
# Generated by Django 4.0.8 on 2022-11-23 08:30 # Generated by Django 4.0.8 on 2022-11-23 08:30
import akarpov.utils.files
import ckeditor_uploader.fields import ckeditor_uploader.fields
import colorfield.fields import colorfield.fields
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import akarpov.utils.files
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -18,73 +19,184 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Tag', name="Tag",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('name', models.CharField(max_length=20, unique=True)), "id",
('color', colorfield.fields.ColorField(blank=True, default='#FF0000', image_field=None, max_length=18, samples=None)), models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=20, unique=True)),
(
"color",
colorfield.fields.ColorField(
blank=True,
default="#FF0000",
image_field=None,
max_length=18,
samples=None,
),
),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
name='Post', name="Post",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('title', models.CharField(max_length=100)), "id",
('body', ckeditor_uploader.fields.RichTextUploadingField()), models.BigAutoField(
('slug', models.SlugField(blank=True, max_length=20)), auto_created=True,
('post_views', models.IntegerField(default=0)), primary_key=True,
('rating', models.IntegerField(default=0)), serialize=False,
('rating_up', models.IntegerField(default=0)), verbose_name="ID",
('rating_down', models.IntegerField(default=0)), ),
('comment_count', models.IntegerField(default=0)), ),
('created', models.DateTimeField(auto_now_add=True)), ("title", models.CharField(max_length=100)),
('edited', models.DateTimeField(auto_now=True)), ("body", ckeditor_uploader.fields.RichTextUploadingField()),
('image', models.ImageField(blank=True, upload_to=akarpov.utils.files.user_file_upload_mixin)), ("slug", models.SlugField(blank=True, max_length=20)),
('image_cropped', models.ImageField(blank=True, upload_to='cropped/')), ("post_views", models.IntegerField(default=0)),
('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='posts', to=settings.AUTH_USER_MODEL)), ("rating", models.IntegerField(default=0)),
('tags', models.ManyToManyField(related_name='posts', to='blog.tag')), ("rating_up", models.IntegerField(default=0)),
("rating_down", models.IntegerField(default=0)),
("comment_count", models.IntegerField(default=0)),
("created", models.DateTimeField(auto_now_add=True)),
("edited", models.DateTimeField(auto_now=True)),
(
"image",
models.ImageField(
blank=True, upload_to=akarpov.utils.files.user_file_upload_mixin
),
),
("image_cropped", models.ImageField(blank=True, upload_to="cropped/")),
(
"creator",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="posts",
to=settings.AUTH_USER_MODEL,
),
),
("tags", models.ManyToManyField(related_name="posts", to="blog.tag")),
], ],
options={ options={
'ordering': ['-created'], "ordering": ["-created"],
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='Comment', name="Comment",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('body', models.CharField(max_length=500)), "id",
('created', models.DateTimeField(auto_now_add=True)), models.BigAutoField(
('rating', models.IntegerField(default=0)), auto_created=True,
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL)), primary_key=True,
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.comment')), serialize=False,
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='blog.post')), verbose_name="ID",
),
),
("body", models.CharField(max_length=500)),
("created", models.DateTimeField(auto_now_add=True)),
("rating", models.IntegerField(default=0)),
(
"author",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="comments",
to=settings.AUTH_USER_MODEL,
),
),
(
"parent",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="blog.comment",
),
),
(
"post",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="comments",
to="blog.post",
),
),
], ],
options={ options={
'ordering': ['-rating'], "ordering": ["-rating"],
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='PostRating', name="PostRating",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('vote_up', models.BooleanField()), "id",
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ratings', to='blog.post')), models.BigAutoField(
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_ratings', to=settings.AUTH_USER_MODEL)), auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("vote_up", models.BooleanField()),
(
"post",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="ratings",
to="blog.post",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="post_ratings",
to=settings.AUTH_USER_MODEL,
),
),
], ],
options={ options={
'unique_together': {('user', 'post')}, "unique_together": {("user", "post")},
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='CommentRating', name="CommentRating",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('vote_up', models.BooleanField()), "id",
('comment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ratings', to='blog.comment')), models.BigAutoField(
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comment_ratings', to=settings.AUTH_USER_MODEL)), auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("vote_up", models.BooleanField()),
(
"comment",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="ratings",
to="blog.comment",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="comment_ratings",
to=settings.AUTH_USER_MODEL,
),
),
], ],
options={ options={
'unique_together': {('comment', 'user')}, "unique_together": {("comment", "user")},
}, },
), ),
] ]

View File

@ -6,12 +6,12 @@
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('blog', '0001_initial'), ("blog", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='comment', name="comment",
options={'ordering': ['-rating', '-created']}, options={"ordering": ["-rating", "-created"]},
), ),
] ]

View File

@ -6,7 +6,7 @@
from akarpov.users.models import User from akarpov.users.models import User
from akarpov.utils.files import user_file_upload_mixin from akarpov.utils.files import user_file_upload_mixin
from utils.string import cleanhtml from akarpov.utils.string import cleanhtml
class Post(models.Model): class Post(models.Model):

View File

@ -23,7 +23,7 @@ def _update_or_create_site_with_sequence(site_model, connection, domain, name):
# site is created. # site is created.
# To avoid this, we need to manually update DB sequence and make sure it's # To avoid this, we need to manually update DB sequence and make sure it's
# greater than the maximum value. # greater than the maximum value.
max_id = site_model.objects.order_by('-id').first().id max_id = site_model.objects.order_by("-id").first().id
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute("SELECT last_value from django_site_id_seq") cursor.execute("SELECT last_value from django_site_id_seq")
(current_id,) = cursor.fetchone() (current_id,) = cursor.fetchone()

View File

@ -11,29 +11,68 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'), ("contenttypes", "0002_remove_content_type_name"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Workspace', name="Workspace",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('name', models.CharField(blank=True, max_length=50)), "id",
('slug', models.SlugField(max_length=8)), models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(blank=True, max_length=50)),
("slug", models.SlugField(max_length=8)),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
name='BaseBlock', name="BaseBlock",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pipeline_blocks', to=settings.AUTH_USER_MODEL)), "id",
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')), models.BigAutoField(
('workspace', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='blocks', to='pipeliner.workspace')), auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"creator",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="pipeline_blocks",
to=settings.AUTH_USER_MODEL,
),
),
(
"polymorphic_ctype",
models.ForeignKey(
editable=False,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="polymorphic_%(app_label)s.%(class)s_set+",
to="contenttypes.contenttype",
),
),
(
"workspace",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="blocks",
to="pipeliner.workspace",
),
),
], ],
options={ options={
'abstract': False, "abstract": False,
'base_manager_name': 'objects', "base_manager_name": "objects",
}, },
), ),
] ]

View File

@ -15,6 +15,10 @@ class Meta:
} }
def create(self, validated_data): def create(self, validated_data):
user = self.context["request"].user.is_authenticated if self.context["request"].user else None user = (
self.context["request"].user.is_authenticated
if self.context["request"].user
else None
)
qr = simple.run(words=validated_data["body"], user=user) qr = simple.run(words=validated_data["body"], user=user)
return qr return qr

View File

@ -1,10 +1,10 @@
from rest_framework import generics from rest_framework import generics
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from rest_framework.viewsets import GenericViewSet
from akarpov.tools.qr.api.serializers import QRSerializer
from akarpov.tools.qr.models import QR from akarpov.tools.qr.models import QR
from .serializers import QRSerializer
class QRViewSet(generics.ListCreateAPIView, generics.RetrieveAPIView, GenericViewSet): class QRViewSet(generics.ListCreateAPIView, generics.RetrieveAPIView, GenericViewSet):

View File

@ -4,8 +4,8 @@
from django.core.files import File from django.core.files import File
from akarpov.tools.qr.models import QR from akarpov.tools.qr.models import QR
from akarpov.utils.generators import generate_charset
from akarpov.users.models import User from akarpov.users.models import User
from akarpov.utils.generators import generate_charset
def run(words: str, path: str = "/tmp/", user: User = None) -> QR: def run(words: str, path: str = "/tmp/", user: User = None) -> QR:

View File

@ -1,4 +1,4 @@
from django.urls import path, include from django.urls import include, path
app_name = "tools" app_name = "tools"
urlpatterns = [path("qr/", include("akarpov.tools.qr.urls", namespace="qr"))] urlpatterns = [path("qr/", include("akarpov.tools.qr.urls", namespace="qr"))]

View File

@ -1,4 +1,5 @@
from django.urls import path from django.urls import path
from .views import ( from .views import (
UserListViewSet, UserListViewSet,
UserRetireUpdateSelfViewSet, UserRetireUpdateSelfViewSet,

View File

@ -1,47 +1,143 @@
# Generated by Django 4.0.8 on 2022-11-23 08:11 # Generated by Django 4.0.8 on 2022-11-23 08:11
import akarpov.utils.files
import django.contrib.auth.models import django.contrib.auth.models
import django.contrib.auth.validators import django.contrib.auth.validators
from django.db import migrations, models from django.db import migrations, models
import django.utils.timezone import django.utils.timezone
import akarpov.utils.files
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('auth', '0012_alter_user_first_name_max_length'), ("auth", "0012_alter_user_first_name_max_length"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='User', name="User",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('password', models.CharField(max_length=128, verbose_name='password')), "id",
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), models.BigAutoField(
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), auto_created=True,
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), primary_key=True,
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), serialize=False,
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), verbose_name="ID",
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), ),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), ),
('name', models.CharField(blank=True, max_length=255, verbose_name='Name of User')), ("password", models.CharField(max_length=128, verbose_name="password")),
('about', models.TextField(blank=True, max_length=100, verbose_name='Description')), (
('image', models.ImageField(blank=True, upload_to=akarpov.utils.files.user_file_upload_mixin)), "last_login",
('image_cropped', models.ImageField(blank=True, upload_to='cropped/')), models.DateTimeField(
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), blank=True, null=True, verbose_name="last login"
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), ),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of "
"deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
(
"name",
models.CharField(
blank=True, max_length=255, verbose_name="Name of User"
),
),
(
"about",
models.TextField(
blank=True, max_length=100, verbose_name="Description"
),
),
(
"image",
models.ImageField(
blank=True, upload_to=akarpov.utils.files.user_file_upload_mixin
),
),
("image_cropped", models.ImageField(blank=True, upload_to="cropped/")),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each "
"of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
], ],
options={ options={
'verbose_name': 'user', "verbose_name": "user",
'verbose_name_plural': 'users', "verbose_name_plural": "users",
'abstract': False, "abstract": False,
}, },
managers=[ managers=[
('objects', django.contrib.auth.models.UserManager()), ("objects", django.contrib.auth.models.UserManager()),
], ],
), ),
] ]

View File

@ -1,17 +1,7 @@
import pytest from akarpov.users.models import User
pytestmark = pytest.mark.django_db
class TestUser: def test_user_create(user: User):
@pytest.fixture password = "123"
def user_with_code(self, user_factory): user.set_password(password)
return user_factory(user_code="1234") assert user.check_password(password)
def test_send_code(self, mailoutbox, user_factory):
user_with_code.send_code()
assert len(mailoutbox) == 1
m = mailoutbox[0]
assert list(m.to) == [user_with_code.email]
assert "1234" in m.body