Skip to content

Aalerti/LinkedLifeNetwotk-hackaton-project

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

100 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

💔 «Всё Сложно» — Social Network

Социальная сеть для людей, которые устали смотреть одинаковые рекомендации и хотят видеть принципиально новый контент в своей ленте
Создана за 48 часов на хакатоне командой из 4 человек.


👥 Команда

Роль Стек
Backend Python, Django REST Framework, JWT
Frontend JavaScript / React
Frontend JavaScript / React
Design Figma

Этот README описывает backend-часть проекта, разработанную мной.


💡 О проекте

«Всё Сложно» — полноценная социальная сеть с лентой, сообществами, личными сообщениями и системой дружбы. Дружба определяется автоматически через взаимную подписку: если ты подписался на человека, а он — на тебя, вы друзья. Всё как в жизни.

Что реализовано

  • Регистрация и авторизация через JWT-токены
  • Профили пользователей с аватаркой, статусом и датой рождения
  • Публикация постов — в личную ленту или в сообщество
  • Умная лента: посты друзей + рекомендации по тематикам + случайные посты
  • Лайки на постах (toggle: поставил/убрал)
  • Комментарии к постам
  • Сообщества с тематиками и системой предмодерации
  • Личные сообщения (диалоги, inbox, пометка "прочитано")
  • Уведомления (новый подписчик, появление взаимной дружбы)
  • Кастомные права доступа (только автор может редактировать свой пост/профиль)
  • Management-команда для наполнения БД тестовыми данными

⚙️ Технологии (Backend)

Технология Назначение
Python 3.12 Основной язык
Django 5.2 Web-фреймворк
Django REST Framework Построение REST API
Djoser Регистрация, авторизация, управление пользователями
SimpleJWT JWT-токены (Access 1 день / Refresh 7 дней)
django-cors-headers CORS для работы с фронтендом
django-filter Фильтрация queryset'ов
Faker Генерация тестовых данных
SQLite База данных (для разработки)

🗂️ Структура Backend

backend/
├── api/
│   ├── models.py          # Все модели: Profile, Post, Community, Like, Message...
│   ├── serializers.py     # Сериализаторы + бизнес-логика полей
│   ├── views.py           # ViewSet'ы для всех ресурсов
│   ├── urls.py            # Маршруты (DefaultRouter)
│   ├── permissions.py     # Кастомные права доступа
│   ├── admin.py           # Регистрация моделей в Django Admin
│   └── management/
│       └── commands/
│           └── fill_db.py # Команда для наполнения БД тестовыми данными
├── socialNetworkLLM/
│   ├── settings.py        # Настройки проекта
│   ├── urls.py            # Корневые маршруты
│   ├── wsgi.py
│   └── asgi.py
└── manage.py

🚀 Запуск проекта

Быстрый старт (для всей команды)

# Frontend
cd frontend
npm install
npm start

# Backend (в отдельном терминале)
cd backend
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver

Наполнить базу тестовыми данными

python manage.py fill_db

Создаст: 15 пользователей, 8 сообществ, 100 постов, 200 лайков.
Пароль всех тестовых пользователей: password123


🗃️ Модели данных

Схема связей

User (Django built-in)
 ├── Profile          (OneToOne)   — никнейм, аватар, статус, дата рождения
 ├── Post             (ForeignKey) — текст, изображение, флаг публикации
 ├── Subscription     (ForeignKey) — подписки (subscriber → target_user)
 ├── Like             (ManyToMany) — лайки на постах
 ├── Comment          (ForeignKey) — комментарии к постам
 ├── Message          (ForeignKey) — личные сообщения
 └── Notification     (ForeignKey) — уведомления

Community
 ├── creator          (ForeignKey → User)
 ├── members          (ManyToMany → User)
 ├── topic            (ForeignKey → Topic)
 └── needs_moderation (Boolean)   — предмодерация постов

Логика дружбы

Дружба — это взаимная подписка. Специальная модель Friend не нужна.
При создании подписки срабатывает Django Signal, который:

  1. Отправляет уведомление целевому пользователю: «X подписался на вас»
  2. Проверяет взаимность — если да, отправляет обоим: «Вы теперь друзья с Y»
# models.py — сигнал на создание подписки
@receiver(post_save, sender=Subscription)
def create_subscription_notification(sender, instance, created, **kwargs):
    if created:
        Notification.objects.create(recipient=instance.target_user, ...)
        is_mutual = Subscription.objects.filter(...).exists()
        if is_mutual:
            # Уведомления обоим

Предмодерация постов в сообществах

Каждое сообщество имеет флаг needs_moderation. Если он включён — пост уходит на проверку (is_published=False). Создатель сообщества публикует без ограничений.

# views.py — логика при создании поста
if community.needs_moderation and community.creator != request.user:
    is_published = False  # Ждёт модерации
else:
    is_published = True   # Публикуется сразу

📡 API Reference

Авторизация

Все защищённые эндпоинты требуют заголовок:

Authorization: Bearer <access_token>
Метод URL Описание
POST /auth/users/ Регистрация
POST /auth/jwt/create/ Получить токен
POST /auth/jwt/refresh/ Обновить токен
GET /auth/users/me/ Данные текущего пользователя
PATCH /auth/users/me/ Редактировать профиль

Пример регистрации:

POST /auth/users/
{
  "username": "john_doe",
  "email": "john@example.com",
  "password": "securepass123",
  "nickname": "Джон",
  "birth_date": "13.05.2000"
}

Дата рождения принимается в двух форматах: ДД.ММ.ГГГГ и ГГГГ-ММ-ДД.


Профили /api/profiles/

Метод URL Описание
GET /api/profiles/ Список всех профилей
GET /api/profiles/{id}/ Профиль пользователя
PATCH /api/profiles/{id}/ Редактировать (только владелец)

Профиль содержит: nickname, bio, avatar, status, birth_date, posts_count, friends_count, friends[], is_subscribed, is_friend.

Поиск: GET /api/profiles/?search=john — поиск по username и nickname.


Посты /api/posts/

Метод URL Описание
GET /api/posts/ Все опубликованные посты
POST /api/posts/ Создать пост
PATCH /api/posts/{id}/ Редактировать (только автор)
DELETE /api/posts/{id}/ Удалить (только автор)
POST /api/posts/{id}/like/ Поставить / убрать лайк
GET /api/posts/feed/ Персональная лента
GET /api/posts/random/ Случайный пост

Фильтрация: ?author=1, ?community=2
Поиск: ?search=текст
Сортировка: ?ordering=-created_at

Алгоритм ленты (/feed/):

1. Посты от подписок + посты из сообществ пользователя (до 10)
2. Рекомендации по тематикам сообществ пользователя (до 5)
3. Если лента < 10 постов — добиваем случайными

Сообщества /api/communities/

Метод URL Описание
GET /api/communities/ Все сообщества (случайный порядок)
POST /api/communities/ Создать сообщество
GET /api/communities/my/ Мои сообщества
POST /api/communities/{id}/join/ Вступить
POST /api/communities/{id}/leave/ Выйти

Подписки /api/subscriptions/

Метод URL Описание
POST /api/subscriptions/ Подписаться (target_user_id)
POST /api/subscriptions/unfollow/ Отписаться (target_user_id)
GET /api/subscriptions/?subscriber=1 Подписки пользователя
GET /api/subscriptions/?target_user=1 Подписчики пользователя

Сообщения /api/messages/

Метод URL Описание
POST /api/messages/ Отправить сообщение
GET /api/messages/conversation/?with=5 Переписка с пользователем по ID
GET /api/messages/conversation/?handle=john Переписка по username
GET /api/messages/inbox/ Список всех диалогов

При открытии переписки все непрочитанные сообщения автоматически помечаются как прочитанные.


Уведомления /api/notifications/

Метод URL Описание
GET /api/notifications/ Мои уведомления
GET /api/notifications/auto_read/ Получить и пометить прочитанными
POST /api/notifications/mark_all_read/ Пометить все прочитанными

Комментарии /api/comments/

Метод URL Описание
GET /api/comments/?post=1 Комментарии к посту
POST /api/comments/ Оставить комментарий
DELETE /api/comments/{id}/ Удалить (только автор)

🔐 Права доступа

Класс Описание
IsAuthorOrReadOnly Читать может любой, редактировать — только автор поста/комментария
IsProfileOwnerOrReadOnly Читать профиль может любой, менять — только владелец
IsCommunityCreatorOrReadOnly Изменять сообщество — только создатель

🌱 Валидация при регистрации

Кастомный сериализатор CustomUserCreateSerializer проверяет:

  • nickname — обязательное поле
  • birth_date — принимает два формата, не может быть в будущем, минимальный возраст — 12 лет
if parsed_date.year < datetime.now().date().year - 12:
    raise ValidationError("Для регистрации вам должно быть больше 12 лет!")

📦 Зависимости

django
djangorestframework
djoser
djangorestframework-simplejwt
django-cors-headers
django-filter
Pillow
Faker

Сделано за 48 часов на хакатоне «Всё Сложно». Бэкенд — с нуля, без магии.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 39.6%
  • CSS 35.7%
  • Python 17.9%
  • HTML 6.8%