Skip to content

Commit 62e3f45

Browse files
Merge pull request #9 from RustamovAkrom/main
Main
2 parents f5bd03b + 48b5218 commit 62e3f45

21 files changed

+312
-632
lines changed

.env-example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ DEBUG=True
99
#### Django allowed hosts default localhost, 127.0.0.1 ####
1010
ALLOWED_HOSTS=localhost,127.0.0.1
1111

12+
# Django mode development or production
13+
DJANGO_SETTINGS_MODULE=core.settings.development # default
14+
1215
#### JWT (RS256) private, public keys default ####
1316
PRIVATE_KEY_PATH=security_settings/private_key.pem
1417
PUBLIC_KEY_PATH=security_settings/public_key.pem
@@ -22,3 +25,9 @@ POSTGRES_USER=POSTGRES_USER
2225
POSTGRES_PASSWORD=POSTGRES_PASSWORD
2326
POSTGRES_HOST=localhost
2427
POSTGRES_PORT=5432
28+
29+
30+
#### Django Admin param ####
31+
ADMIN_USERNAME=admin
32+
ADMIN_PASSWORD=password
33+
ADMIN_EMAIL=admin@example.com

README.md

Lines changed: 138 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,142 @@
1-
# Django Blog app adevanced project
1+
![logo](logo.png)
2+
# Blog App
23

3-
![logo](/logo.png)
4+
Blog App — это веб-приложение на Django для создания, управления и просмотра блог-постов с аутентификацией через JWT-токены.
45

5-
## Technologies:
6-
- Django
7-
- Django REST
8-
- Django Simple JWT
9-
- Authentication for JWT (RS256)
10-
- HTML, CSS, JavaScript, Bootstrap
11-
- SEO Optimizations
6+
## Основные возможности
127

13-
## Databases:
14-
+ PostgreSQL
15-
+ SQLite3
8+
- **Создание постов**: авторизированные пользователи могут добавлять и редактировать свои посты.
9+
- **Чтение постов**: все пользователи могут просматривать посты.
10+
- **Авторизация через JWT**: безопасная авторизация с использованием Access и Refresh токенов (Algorithm RS256).
1611

17-
[Documentations](docs/index.md)
12+
## Стек технологий
13+
14+
- **Backend**: Django, Django REST Framework
15+
- **Аутентификация**: JWT (с использованием `djangorestframework-simplejwt`)
16+
- **База данных**: PostgreSQL (или SQLite для локальной разработки)
17+
- **Кэширование**: Django Cache (опционально, для оптимизации производительности)
18+
19+
## Установка и запуск
20+
21+
### Клонирование репозитория
22+
23+
```bash
24+
git clone https://github.com/RustamovAkrom/Blog-2.git
25+
cd Blog-2
26+
```
27+
28+
### Настройка виртуального окружения
29+
30+
Создайте и активируйте виртуальное окружение:
31+
32+
```bash
33+
python -m venv venv
34+
source venv/bin/activate # для Linux/macOS
35+
venv\Scripts\activate # для Windows
36+
```
37+
38+
### Установка зависимостей
39+
40+
Установите необходимые зависимости:
41+
42+
```bash
43+
pip install -r requirements.txt
44+
```
45+
46+
### Настройка переменных окружения
47+
48+
Создайте файл `.env` в корне проекта и добавьте туда настройки для базы данных и JWT. Пример:
49+
50+
```sh
51+
#!/bin/bash
52+
53+
SECRET_KEY=<your django secret key>
54+
55+
DEBUG=True # default
56+
57+
ALLOWED_HOSTS=localhost,127.0.0.1 # default
58+
59+
# `core.settings.development` or `core.setting.production`
60+
DJANGO_SETTINGS_MODULE=core.settings.development # default
61+
62+
PRIVATE_KEY_PATH=security_settings/private_key.pem # default
63+
PUBLIC_KEY_PATH=security_settings/public_key.pem # default
64+
65+
DATABASE_ENVIRON=sqlite # sqlite or postgres
66+
67+
# PostgreSQL configruations
68+
POSTGRES_NAME=<your database name>
69+
POSTGRES_USER=<your database user>
70+
POSTGRES_PASSWORD=<your database password>
71+
POSTGRES_HOST=localhost # default
72+
POSTGRES_PORT=5432 # default
73+
74+
ADMIN_USERNAME=admin # default
75+
ADMIN_PASSWORD=password # default
76+
ADMIN_EMAIL=admin@example.com # default
77+
```
78+
79+
### Применение миграций и создание суперпользователя
80+
81+
Примените миграции и создайте суперпользователя для доступа к админ-панели:
82+
83+
```bash
84+
python manage.py migrate
85+
python manage.py createadmin
86+
```
87+
88+
### Запуск сервера
89+
90+
Запустите сервер разработки:
91+
92+
```bash
93+
python manage.py runserver
94+
```
95+
96+
Теперь ваше приложение доступно по адресу: `http://127.0.0.1:8000`
97+
98+
## Аутентификация через JWT
99+
100+
Blog App использует JWT для аутентификации. При входе в систему клиент получает два токена:
101+
- **Access Token** — для доступа к защищённым маршрутам.
102+
- **Refresh Token** — для обновления Access Token.
103+
104+
<!-- ### Эндпоинты для аутентификации
105+
106+
- **`/api/token/`** — получение Access и Refresh токенов (логин).
107+
- **`/api/token/refresh/`** — обновление Access Token с помощью Refresh Token.
108+
- **`/api/token/verify/`** — проверка действительности токена. -->
109+
110+
### Пример использования JWT
111+
112+
1. Получите Access и Refresh токены с помощью `/api/token/`.
113+
2. Используйте Access Token для доступа к защищённым эндпоинтам, добавляя его в заголовок запросов:
114+
115+
```http
116+
Authorization: Bearer <access_token>
117+
```
118+
119+
3. Когда Access Token истекает, обновите его с помощью `/api/token/refresh/`, отправляя Refresh Token в теле запроса.
120+
121+
<!-- ## API эндпоинты
122+
123+
- **GET /api/posts/**: Просмотр всех постов
124+
- **POST /api/posts/**: Создание нового поста (только для авторизованных пользователей)
125+
- **GET /api/posts/<id>/**: Просмотр поста по ID
126+
- **PUT /api/posts/<id>/**: Обновление поста (только для автора)
127+
- **DELETE /api/posts/<id>/**: Удаление поста (только для автора) -->
128+
129+
## Структура проекта
130+
131+
- **apps/users**: Приложение для управления пользователями и аутентификацией.
132+
- **apps/posts**: Приложение для создания, редактирования и удаления блог-постов.
133+
- **middleware**: JWT Middleware для авторизации с использованием токенов.
134+
- **settings**: Файл настроек Django, включая конфигурацию базы данных и кэширования.
135+
136+
## Кэширование
137+
138+
Для ускорения работы Blog App можно использовать кэширование JWT-токенов. Этот механизм позволяет кэшировать данные пользователей для быстрого доступа без необходимости каждый раз проверять токен.
139+
140+
## Лицензия
141+
142+
Этот проект лицензирован на условиях **MIT License**.
Lines changed: 40 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,75 @@
1-
# Generated by Django 5.1.1 on 2024-11-10 05:49
1+
# Generated by Django 5.1.1 on 2024-11-12 14:17
22

3+
import django.db.models.deletion
4+
from django.conf import settings
35
from django.db import migrations, models
46

57

68
class Migration(migrations.Migration):
79

810
initial = True
911

10-
dependencies = []
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
]
1115

1216
operations = [
1317
migrations.CreateModel(
14-
name="Post",
18+
name='Post',
1519
fields=[
16-
(
17-
"id",
18-
models.BigAutoField(
19-
auto_created=True,
20-
primary_key=True,
21-
serialize=False,
22-
verbose_name="ID",
23-
),
24-
),
25-
("created_at", models.DateTimeField(auto_now_add=True)),
26-
("updated_at", models.DateTimeField(auto_now=True)),
27-
(
28-
"title",
29-
models.CharField(
30-
db_index=True, max_length=120, verbose_name="title"
31-
),
32-
),
33-
(
34-
"slug",
35-
models.SlugField(max_length=255, unique=True, verbose_name="slug"),
36-
),
37-
("content", models.TextField(verbose_name="content")),
38-
("publisher_at", models.DateField(verbose_name="publisher at")),
39-
(
40-
"is_active",
41-
models.BooleanField(default=False, verbose_name="active"),
42-
),
43-
(
44-
"watching",
45-
models.BigIntegerField(default=0, verbose_name="watching"),
46-
),
20+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21+
('created_at', models.DateTimeField(auto_now_add=True)),
22+
('updated_at', models.DateTimeField(auto_now=True)),
23+
('title', models.CharField(db_index=True, max_length=120, verbose_name='title')),
24+
('slug', models.SlugField(max_length=255, unique=True, verbose_name='slug')),
25+
('content', models.TextField(verbose_name='content')),
26+
('publisher_at', models.DateField(verbose_name='publisher at')),
27+
('is_active', models.BooleanField(default=False, verbose_name='active')),
28+
('watching', models.BigIntegerField(default=0, verbose_name='watching')),
29+
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='posts', to=settings.AUTH_USER_MODEL)),
4730
],
4831
options={
49-
"verbose_name": "Post",
50-
"verbose_name_plural": "Posts",
51-
"db_table": "posts",
32+
'verbose_name': 'Post',
33+
'verbose_name_plural': 'Posts',
34+
'db_table': 'posts',
5235
},
5336
),
5437
migrations.CreateModel(
55-
name="PostComment",
38+
name='PostComment',
5639
fields=[
57-
(
58-
"id",
59-
models.BigAutoField(
60-
auto_created=True,
61-
primary_key=True,
62-
serialize=False,
63-
verbose_name="ID",
64-
),
65-
),
66-
("created_at", models.DateTimeField(auto_now_add=True)),
67-
("updated_at", models.DateTimeField(auto_now=True)),
68-
("message", models.TextField(verbose_name="message")),
40+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
41+
('created_at', models.DateTimeField(auto_now_add=True)),
42+
('updated_at', models.DateTimeField(auto_now=True)),
43+
('message', models.TextField(verbose_name='message')),
44+
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_comments', to='blog.post')),
45+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_comments', to=settings.AUTH_USER_MODEL)),
6946
],
7047
options={
71-
"abstract": False,
48+
'abstract': False,
7249
},
7350
),
7451
migrations.CreateModel(
75-
name="PostCommentLike",
52+
name='PostCommentLike',
7653
fields=[
77-
(
78-
"id",
79-
models.BigAutoField(
80-
auto_created=True,
81-
primary_key=True,
82-
serialize=False,
83-
verbose_name="ID",
84-
),
85-
),
54+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
55+
('comment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_comment_likes', to='blog.postcomment')),
56+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_comment_likes', to=settings.AUTH_USER_MODEL)),
8657
],
8758
),
8859
migrations.CreateModel(
89-
name="PostDislike",
60+
name='PostDislike',
9061
fields=[
91-
(
92-
"id",
93-
models.BigAutoField(
94-
auto_created=True,
95-
primary_key=True,
96-
serialize=False,
97-
verbose_name="ID",
98-
),
99-
),
62+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
63+
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_dislikes', to='blog.post')),
64+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_dislikes', to=settings.AUTH_USER_MODEL)),
10065
],
10166
),
10267
migrations.CreateModel(
103-
name="PostLike",
68+
name='PostLike',
10469
fields=[
105-
(
106-
"id",
107-
models.BigAutoField(
108-
auto_created=True,
109-
primary_key=True,
110-
serialize=False,
111-
verbose_name="ID",
112-
),
113-
),
70+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
71+
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_likes', to='blog.post')),
72+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_likes', to=settings.AUTH_USER_MODEL)),
11473
],
11574
),
11675
]

0 commit comments

Comments
 (0)