ucp panel с нуля

  • Автор темы casimiro
  • Дата начала
  • Ответы 23
  • Просмотры 1 тыс.
  • IV <> V
    • Следите за дальнейшими новостями в официальном паблике проекта в ВК или в треде новостей проекта.
    • Регистрация персонажей открыта!
    • Регистрация топиков персонажей, фракционных топиков и других тредов, связанных с ролевым миром - вновь действуют.

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
4f9c20071a1398ff3c0eef3fdfac2e1a.webp


***
Всем здарова, в общем тема сама за себя тема говорит. Будет делать свою ucp-panel. зачем? Ну по угарчику, потому что это интересно мне, а кто-то будет читать и может чет дельное напишет или просто чему то научится.. я сразу говорю, что с samp/rage проектами не работал, поэтому буду писать так, как я себе представляю без какого либо проекта, и представлять какие-то там модельки. будем использовать pgsql в качестве бд, потому что ucp я все же делаю для rage мультиплеера. так, что высеры про ублюдскую базу данных по моему мнению mysql - писать не надо. будем представлять, что работаем именно с postgresql, ибо на rage в отличие от сампика, как я понял она функционирует нормальды.

Технологии : django + pgsql

Критика : Если вы не разбираетесь, читайте и слушайте. Личка у меня всегда открыта, прошу вас не засорять топик, ибо если кто-то захочет для себя что-то подчеркнуть будет не в кайф читать ваше говно.

upd : Сразу говорю из меня верстальщик, как из мошенника - честный полицейский. Но 2023 год и можно это всё решить куда проще. Поэтому будем использовать bootstrap и готовые шаблоны, которые буду подгонять под себя. Поэтому критика на верстку тоже мне не всралась, буду делать так чтобы более менее этим было не отвратно пользоваться.
 
Последнее редактирование:

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
База данных :
Мне слишком впадлу писать юзера с нуля, поэтому схитрим. А именно сделаем наследование от abstractuser, который встроен в django и создадим отдельную таблицу для связи этих двух пидоров. AbstractUser будет из себя представлять аккаунт, к которому привязаны персонажи.

А теперь к демо-версии, которую я нахуячил пьяный и полюбому ещё пять тысяч раз перепишу.

Python:
# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    pass


class Account(models.Model):
    user = models.ForeignKey(
        User,
        related_name='user',
        on_delete=models.PROTECT,
        null=True,
    )
    status_option = (
        ('Одобрено', 'Одобрено'),
        ('На рассмотрение', 'На рассмотрение'),
        ('Отклонено', 'Отклонено'),
        ('Заблокирован', 'Заблокирован')
    )
    status = models.CharField(
        verbose_name='Статус аккаунта',
        choices=status_option,
        max_length=20,
        default=status_option[1][0]
    )
    name_character = models.CharField(
        verbose_name='Имя персонажа',
        max_length=15,
        default='Name'
    )
    surname_character = models.CharField(
        verbose_name='Фамилия персонажа',
        max_length=15,
        default='Surname'
    )
    orientation_type = (
        ('M', 'Мужской'),
        ('Ж', 'Женский')
    )
    age = models.IntegerField(
        verbose_name='Возраст',
    )
    money = models.IntegerField(
        verbose_name='Деньги',
        default=2000
    )
    color_type = (
        ('Светлокожий', 'Светлокожий'),
        ('Темнокожий', 'Темнокожий')
    )
    orientation = models.CharField(
        verbose_name='Выбор пола',
        max_length=8,
        choices=orientation_type,
        default=orientation_type[0][1]
    )
    quintet = models.TextField(
        verbose_name='Квента',
        default='Квента'
    )
    situation_0 = models.TextField(
        verbose_name='Ситауция 2',
        default='Test'
    )
    situation_1 = models.TextField(
        verbose_name='Ситуация 1',
        default='test'
    )

    def __str__(self):
        return f'{self.name_character} {self.surname_character}'

    class Meta:
        verbose_name = 'Персонажи'
 
Последнее редактирование:

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
samp юзает mysql только, мультиплееры гта 5 в зависимости от ЯП. JS - mongo/postgres иногда mysql, C# - mysql/postgres
я это уточнил ещё выше, саввин! Я сказал, что меня не ебет, я буду писать на своём любимом postgresql, и будем импровизировать, что используем pgsql для rage.
 

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
samp юзает mysql только, мультиплееры гта 5 в зависимости от ЯП. JS - mongo/postgres иногда mysql, C# - mysql/postgres
один хуй, то что в бэке будет использоваться на сайте - похуй. можно подключить к нему готовую бдшку, и радоваться жизни. ибо использовать node для написания бэка - для меня такая себе идея
 

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
Я сразу отметил, что верстка моя слабая сторона. Поэтому держите чё получилось с личным кабинетом. Два вечера и думаю окончательный вариант будет готов. Далее можно уже приступать к написанию бэка.

cj3vlRWZ.jpg



с админ панелью тоже самое думаю провернуть, шаблоны не менять.

всем спасибо за внимание!
 

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
здарова. тишина, да и только. я выше писал, что пьяный написал модельку для бд. так вот, она оказалось гавном и я её переписал =)

из основного, что я помню, ибо параллельно пишу уже заказик на фрилансе и на это, как понимаете меньше времени уделяю(ucp)! так вот изменил связь, чтобы одного персонажа можно было создавать на 1 аккаунт и утроил эти модели. так же добавил валидаторы для возраста и имени. имя форматик всем любимы Name_Surname, чтобы с проверкой на уникальность не заморачиваться и не делать лишние запросы в базу данных при проверке на уникальность сего творения. как говорится, хорошие запросы надо писать сразу, чтобы потом не удивляться схуяли так много запросов лишних

вот код моих моделей, не удивляйтесь он повторяется, поэтому и много

Python:
# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from .validators import validate_fullname, validate_age


class User(AbstractUser):
    pass


class AccountOne(models.Model):
    user = models.OneToOneField(
        User,
        related_name='user_1',
        on_delete=models.PROTECT,
        null=True,
    )
    status_option = (
        ('Одобрено', 'Одобрено'),
        ('На рассмотрение', 'На рассмотрение'),
        ('Отклонено', 'Отклонено'),
        ('Заблокирован', 'Заблокирован'),
        ('Мертв', 'Мертв')
    )
    status = models.CharField(
        verbose_name='Статус аккаунта',
        choices=status_option,
        max_length=20,
        default=status_option[1][0]
    )
    fullname = models.CharField(
        verbose_name='Имя и Фамилия персонажа',
        max_length=15,
        unique=True,
        validators=[validate_fullname]
    )
    orientation_type = (
        ('M', 'Мужской'),
        ('Ж', 'Женский')
    )
    age = models.IntegerField(
        verbose_name='Возраст',
        validators=[validate_age]
    )
    money = models.IntegerField(
        verbose_name='Деньги',
        default=2000
    )
    color_type = (
        ('Светлокожий', 'Светлокожий'),
        ('Темнокожий', 'Темнокожий')
    )
    orientation = models.CharField(
        verbose_name='Выбор пола',
        max_length=8,
        choices=orientation_type,
    )
    quintet = models.TextField(
        verbose_name='Квента',
        default='Квента'
    )
    situation_0 = models.TextField(
        verbose_name='Ситауция 2',
        default='Test'
    )
    situation_1 = models.TextField(
        verbose_name='Ситуация 1',
        default='test'
    )

    def __str__(self):
        return f'{self.fullname}'

    class Meta:
        verbose_name = 'Персонажи'


class AccountTwo(models.Model):
    user = models.OneToOneField(
        User,
        related_name='user_2',
        on_delete=models.PROTECT,
        null=True,
    )
    status_option = (
        ('Одобрено', 'Одобрено'),
        ('На рассмотрение', 'На рассмотрение'),
        ('Отклонено', 'Отклонено'),
        ('Заблокирован', 'Заблокирован'),
        ('Мертв', 'Мертв')
    )
    status = models.CharField(
        verbose_name='Статус аккаунта',
        choices=status_option,
        max_length=20,
        default=status_option[1][0]
    )
    fullname = models.CharField(
        verbose_name='Имя и Фамилия персонажа',
        max_length=15,
        unique=True,
        validators=[validate_fullname]
    )
    orientation_type = (
        ('M', 'Мужской'),
        ('Ж', 'Женский')
    )
    age = models.IntegerField(
        verbose_name='Возраст',
        validators=[validate_age]
    )
    money = models.IntegerField(
        verbose_name='Деньги',
        default=2000
    )
    color_type = (
        ('Светлокожий', 'Светлокожий'),
        ('Темнокожий', 'Темнокожий')
    )
    orientation = models.CharField(
        verbose_name='Выбор пола',
        max_length=8,
        choices=orientation_type,
    )
    quintet = models.TextField(
        verbose_name='Квента',
        default='Квента'
    )
    situation_0 = models.TextField(
        verbose_name='Ситауция 2',
        default='Test'
    )
    situation_1 = models.TextField(
        verbose_name='Ситуация 1',
        default='test'
    )

    def __str__(self):
        return f'{self.fullname}'

    class Meta:
        verbose_name = 'Персонажи'


class AccountThree(models.Model):
    user = models.OneToOneField(
        User,
        related_name='user_3',
        on_delete=models.PROTECT,
        null=True,
    )
    status_option = (
        ('Одобрено', 'Одобрено'),
        ('На рассмотрение', 'На рассмотрение'),
        ('Отклонено', 'Отклонено'),
        ('Заблокирован', 'Заблокирован'),
        ('Мертв', 'Мертв')
    )
    status = models.CharField(
        verbose_name='Статус аккаунта',
        choices=status_option,
        max_length=20,
        default=status_option[1][0]
    )
    fullname = models.CharField(
        verbose_name='Имя и Фамилия персонажа',
        max_length=15,
        unique=True,
        validators=[validate_fullname]
    )
    orientation_type = (
        ('M', 'Мужской'),
        ('Ж', 'Женский')
    )
    age = models.IntegerField(
        verbose_name='Возраст',
        validators=[validate_age]
    )
    money = models.IntegerField(
        verbose_name='Деньги',
        default=2000
    )
    color_type = (
        ('Светлокожий', 'Светлокожий'),
        ('Темнокожий', 'Темнокожий')
    )
    orientation = models.CharField(
        verbose_name='Выбор пола',
        max_length=8,
        choices=orientation_type,
    )
    quintet = models.TextField(
        verbose_name='Квента',
        default='Квента'
    )
    situation_0 = models.TextField(
        verbose_name='Ситауция 2',
        default='Test'
    )
    situation_1 = models.TextField(
        verbose_name='Ситуация 1',
        default='test'
    )

    def __str__(self):
        return f'{self.fullname}'

    class Meta:
        verbose_name = 'Персонажи'

Так и теперь валидаторов код, я создал отдельный файл, чтобы они не путались в моделях. Хотя многие любят писать в уже созданных файлах django, но мы нетакуси и реализовали в отдельном файле и подключили!

Python:
# validators.py
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _


def validate_fullname(value):
    if value not in '_':
        raise ValidationError(
            _("Напишите ваше имя в формате Name_Surname"),
            params={"value": value},
        )


def validate_age(value):
    if value > 60:
        raise ValidationError(
            _("Ваш возраст больше 60"),
            params={"value": value},
        )
    if value < 15:
        raise ValidationError(
            _("Ваш возраст меньше 15"),
            params={"value": value},
        )


так вот. сегодня/завтра буду показывать паттерн mvc на котором создан django! если хотите более детально, то мяукайте прислушаюсь, обработаю ваши запросы.
 

casimiro

Руководство №2
Заместитель руководителя проекта
3 574
11 241
и главное забыл, вот такая структура проекта пока вырисовывается. она неготовая, поэтому некоторые приложения ещё не созданы

zlNRrAhb.jpg