djresttoolkit 0.6.2__py3-none-any.whl → 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- README.md +65 -5
- {djresttoolkit-0.6.2.dist-info → djresttoolkit-0.7.0.dist-info}/METADATA +66 -6
- {djresttoolkit-0.6.2.dist-info → djresttoolkit-0.7.0.dist-info}/RECORD +9 -7
- src/djresttoolkit/dbseed/models/__init__.py +7 -1
- src/djresttoolkit/dbseed/models/_choice_field.py +17 -0
- src/djresttoolkit/management/commands/dbflush.py +94 -0
- {djresttoolkit-0.6.2.dist-info → djresttoolkit-0.7.0.dist-info}/WHEEL +0 -0
- {djresttoolkit-0.6.2.dist-info → djresttoolkit-0.7.0.dist-info}/entry_points.txt +0 -0
- {djresttoolkit-0.6.2.dist-info → djresttoolkit-0.7.0.dist-info}/licenses/LICENSE +0 -0
README.md
CHANGED
@@ -85,7 +85,67 @@ python manage.py dbseed --count 10
|
|
85
85
|
python manage.py dbseed --model User --seed 42
|
86
86
|
```
|
87
87
|
|
88
|
-
|
88
|
+
Here’s a **concise API reference** for your database flush management command for `djresttoolkit`:
|
89
|
+
|
90
|
+
---
|
91
|
+
|
92
|
+
### 2. DB Flush Command
|
93
|
+
|
94
|
+
```python
|
95
|
+
from djresttoolkit.management.commands import flush
|
96
|
+
```
|
97
|
+
|
98
|
+
#### `manage.py dbflush`
|
99
|
+
|
100
|
+
Command to **delete all records** from the database for all models or a specific model and **reset auto-increment IDs**.
|
101
|
+
|
102
|
+
#### Usage
|
103
|
+
|
104
|
+
```bash
|
105
|
+
python manage.py flush [--model ModelName] [--yes]
|
106
|
+
```
|
107
|
+
|
108
|
+
#### dbflush command options
|
109
|
+
|
110
|
+
- `--model`: Name of the model to flush (case-sensitive, e.g., `User`). If omitted, flushes all models.
|
111
|
+
- `--yes`: Skip confirmation prompt. Without this, the command asks for confirmation before deleting.
|
112
|
+
|
113
|
+
#### dbflush command behavior
|
114
|
+
|
115
|
+
- Deletes all records for the specified model or all models.
|
116
|
+
- Resets primary key sequences for supported databases:
|
117
|
+
|
118
|
+
- PostgreSQL: `ALTER SEQUENCE ... RESTART WITH 1`
|
119
|
+
- SQLite: Deletes from `sqlite_sequence` table
|
120
|
+
- Others: Logs a warning (not implemented).
|
121
|
+
- Uses transactions to ensure safe operations.
|
122
|
+
|
123
|
+
#### dbflush command example
|
124
|
+
|
125
|
+
```bash
|
126
|
+
# Flush all models with confirmation
|
127
|
+
python manage.py dbflush
|
128
|
+
|
129
|
+
# Flush a specific model (User) with confirmation
|
130
|
+
python manage.py dbflush --model User
|
131
|
+
|
132
|
+
# Flush all models without prompt
|
133
|
+
python manage.py dbflush --yes
|
134
|
+
```
|
135
|
+
|
136
|
+
#### Output
|
137
|
+
|
138
|
+
```bash
|
139
|
+
Flushed 10 records from model "User" and reset IDs.
|
140
|
+
```
|
141
|
+
|
142
|
+
or
|
143
|
+
|
144
|
+
```bash
|
145
|
+
Flushed 120 records from all models and reset IDs.
|
146
|
+
```
|
147
|
+
|
148
|
+
### 3. EmailSender
|
89
149
|
|
90
150
|
```python
|
91
151
|
from djresttoolkit.mail import EmailSender, EmailContent, EmailTemplate
|
@@ -134,7 +194,7 @@ EmailSender(content).send(to=["user@example.com"])
|
|
134
194
|
|
135
195
|
- `text`, `html` — template file paths
|
136
196
|
|
137
|
-
###
|
197
|
+
### 4. Custom DRF Exception Handler
|
138
198
|
|
139
199
|
```python
|
140
200
|
from djresttoolkit.views import exception_handler
|
@@ -174,7 +234,7 @@ REST_FRAMEWORK = {
|
|
174
234
|
- Tracks requests in cache and calculates `retry_after`.
|
175
235
|
- Cleans expired timestamps automatically.
|
176
236
|
|
177
|
-
###
|
237
|
+
### 5. Response Time Middleware
|
178
238
|
|
179
239
|
```python
|
180
240
|
from djresttoolkit.middlewares import ResponseTimeMiddleware
|
@@ -192,7 +252,7 @@ ResponseTimeMiddleware(get_response: Callable[[HttpRequest], HttpResponse])
|
|
192
252
|
|
193
253
|
- `get_response`: The next middleware or view callable.
|
194
254
|
|
195
|
-
#### Usage
|
255
|
+
#### Response Time Middleware Usage
|
196
256
|
|
197
257
|
Add it to your Django `MIDDLEWARE` in `settings.py`:
|
198
258
|
|
@@ -221,7 +281,7 @@ X-Response-Time: 0.01234 seconds
|
|
221
281
|
INFO: Request processed in 0.01234 seconds
|
222
282
|
```
|
223
283
|
|
224
|
-
###
|
284
|
+
### 6. Throttle Utilities
|
225
285
|
|
226
286
|
#### `ThrottleInfoJSONRenderer`
|
227
287
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: djresttoolkit
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.7.0
|
4
4
|
Summary: A collection of Django and DRF utilities to simplify API development.
|
5
5
|
Project-URL: Homepage, https://github.com/shaileshpandit141/djresttoolkit
|
6
6
|
Project-URL: Documentation, https://shaileshpandit141.github.io/djresttoolkit
|
@@ -141,7 +141,67 @@ python manage.py dbseed --count 10
|
|
141
141
|
python manage.py dbseed --model User --seed 42
|
142
142
|
```
|
143
143
|
|
144
|
-
|
144
|
+
Here’s a **concise API reference** for your database flush management command for `djresttoolkit`:
|
145
|
+
|
146
|
+
---
|
147
|
+
|
148
|
+
### 2. DB Flush Command
|
149
|
+
|
150
|
+
```python
|
151
|
+
from djresttoolkit.management.commands import flush
|
152
|
+
```
|
153
|
+
|
154
|
+
#### `manage.py dbflush`
|
155
|
+
|
156
|
+
Command to **delete all records** from the database for all models or a specific model and **reset auto-increment IDs**.
|
157
|
+
|
158
|
+
#### Usage
|
159
|
+
|
160
|
+
```bash
|
161
|
+
python manage.py flush [--model ModelName] [--yes]
|
162
|
+
```
|
163
|
+
|
164
|
+
#### dbflush command options
|
165
|
+
|
166
|
+
- `--model`: Name of the model to flush (case-sensitive, e.g., `User`). If omitted, flushes all models.
|
167
|
+
- `--yes`: Skip confirmation prompt. Without this, the command asks for confirmation before deleting.
|
168
|
+
|
169
|
+
#### dbflush command behavior
|
170
|
+
|
171
|
+
- Deletes all records for the specified model or all models.
|
172
|
+
- Resets primary key sequences for supported databases:
|
173
|
+
|
174
|
+
- PostgreSQL: `ALTER SEQUENCE ... RESTART WITH 1`
|
175
|
+
- SQLite: Deletes from `sqlite_sequence` table
|
176
|
+
- Others: Logs a warning (not implemented).
|
177
|
+
- Uses transactions to ensure safe operations.
|
178
|
+
|
179
|
+
#### dbflush command example
|
180
|
+
|
181
|
+
```bash
|
182
|
+
# Flush all models with confirmation
|
183
|
+
python manage.py dbflush
|
184
|
+
|
185
|
+
# Flush a specific model (User) with confirmation
|
186
|
+
python manage.py dbflush --model User
|
187
|
+
|
188
|
+
# Flush all models without prompt
|
189
|
+
python manage.py dbflush --yes
|
190
|
+
```
|
191
|
+
|
192
|
+
#### Output
|
193
|
+
|
194
|
+
```bash
|
195
|
+
Flushed 10 records from model "User" and reset IDs.
|
196
|
+
```
|
197
|
+
|
198
|
+
or
|
199
|
+
|
200
|
+
```bash
|
201
|
+
Flushed 120 records from all models and reset IDs.
|
202
|
+
```
|
203
|
+
|
204
|
+
### 3. EmailSender
|
145
205
|
|
146
206
|
```python
|
147
207
|
from djresttoolkit.mail import EmailSender, EmailContent, EmailTemplate
|
@@ -190,7 +250,7 @@ EmailSender(content).send(to=["user@example.com"])
|
|
190
250
|
|
191
251
|
- `text`, `html` — template file paths
|
192
252
|
|
193
|
-
###
|
253
|
+
### 4. Custom DRF Exception Handler
|
194
254
|
|
195
255
|
```python
|
196
256
|
from djresttoolkit.views import exception_handler
|
@@ -230,7 +290,7 @@ REST_FRAMEWORK = {
|
|
230
290
|
- Tracks requests in cache and calculates `retry_after`.
|
231
291
|
- Cleans expired timestamps automatically.
|
232
292
|
|
233
|
-
###
|
293
|
+
### 5. Response Time Middleware
|
234
294
|
|
235
295
|
```python
|
236
296
|
from djresttoolkit.middlewares import ResponseTimeMiddleware
|
@@ -248,7 +308,7 @@ ResponseTimeMiddleware(get_response: Callable[[HttpRequest], HttpResponse])
|
|
248
308
|
|
249
309
|
- `get_response`: The next middleware or view callable.
|
250
310
|
|
251
|
-
#### Usage
|
311
|
+
#### Response Time Middleware Usage
|
252
312
|
|
253
313
|
Add it to your Django `MIDDLEWARE` in `settings.py`:
|
254
314
|
|
@@ -277,7 +337,7 @@ X-Response-Time: 0.01234 seconds
|
|
277
337
|
INFO: Request processed in 0.01234 seconds
|
278
338
|
```
|
279
339
|
|
280
|
-
###
|
340
|
+
### 6. Throttle Utilities
|
281
341
|
|
282
342
|
#### `ThrottleInfoJSONRenderer`
|
283
343
|
|
@@ -1,12 +1,13 @@
|
|
1
1
|
LICENSE,sha256=8-oZM3yuuTRjySMbVKX9YXYA7Y4M_KhQNBYXPFjeWUo,1074
|
2
|
-
README.md,sha256=
|
2
|
+
README.md,sha256=5bxE-TuyTrqyyWh3iISPe0GtLYyU7bOuCEdooPj_DQo,8418
|
3
3
|
demo/staticfiles/admin/img/LICENSE,sha256=0RT6_zSIwWwxmzI13EH5AjnT1j2YU3MwM9j3U19cAAQ,1081
|
4
4
|
src/djresttoolkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
src/djresttoolkit/admin.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
src/djresttoolkit/apps.py,sha256=nKb5GUIEhAB3IL3lTmEXNc5XuvvaZupH-1CCuYKFrEQ,158
|
7
7
|
src/djresttoolkit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
src/djresttoolkit/dbseed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
src/djresttoolkit/dbseed/models/__init__.py,sha256=
|
9
|
+
src/djresttoolkit/dbseed/models/__init__.py,sha256=uuynQIcfVqEaZN9hF_caI24zm8az23JdXLDrv7xOKTQ,180
|
10
|
+
src/djresttoolkit/dbseed/models/_choice_field.py,sha256=T7LAzbyXqlYp2mtCAKL8E1Da_MEh9RzgLZrFJ7fa4gM,446
|
10
11
|
src/djresttoolkit/dbseed/models/_gen.py,sha256=qBPQaLvh1rcEam0YmE4JBJqpa-Vv5IFlIIagkEMHDVw,206
|
11
12
|
src/djresttoolkit/dbseed/models/_seed_model.py,sha256=0cmbi0VNKjmJbwhjeCFsvb3iKYjok6TJOk6Y2MF_3N4,2443
|
12
13
|
src/djresttoolkit/mail/__init__.py,sha256=tB9SdMlhfWQ640q4aobZ0H1c7fTWalpDL2I-onkr2VI,268
|
@@ -15,6 +16,7 @@ src/djresttoolkit/mail/_models.py,sha256=of5KsLGvsN2OWgDYgdtLEijulg817TXgsLKuUds
|
|
15
16
|
src/djresttoolkit/mail/_types.py,sha256=zf6CcXR1ei_UmZ1nLAJa378OAJ6ftnBICqEOkzXPNw8,646
|
16
17
|
src/djresttoolkit/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
18
|
src/djresttoolkit/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
src/djresttoolkit/management/commands/dbflush.py,sha256=v7rXcuNQDiXLV7p0xzKMNXVeWAN7QKmq2qQQAbhHEEw,3423
|
18
20
|
src/djresttoolkit/management/commands/dbseed.py,sha256=sY87TvvzECG7aQXxsDjr45VzCzJpofLacBK49EYFK8M,4225
|
19
21
|
src/djresttoolkit/middlewares/__init__.py,sha256=GZHU3Yy4xXoEi62tHn0UJNxN6XgGM2_HES8Bt5AS5Lk,100
|
20
22
|
src/djresttoolkit/middlewares/_response_time_middleware.py,sha256=1wCwdkW5Ng6HJo8zx0F7ylms84OGP-1K0kbyG6Vacuk,908
|
@@ -27,8 +29,8 @@ src/djresttoolkit/throttling/_throttle_inspector.py,sha256=Kss6ZxKy-EXq9UGaGprGD
|
|
27
29
|
src/djresttoolkit/views/__init__.py,sha256=XrxBrs6sH4HmUzp41omcmy_y94pSaXAVn01ttQ022-4,76
|
28
30
|
src/djresttoolkit/views/_exceptions/__init__.py,sha256=DrCUxuPNyBR4WhzNutn5HDxLa--q51ykIxSG7_bFsOI,83
|
29
31
|
src/djresttoolkit/views/_exceptions/_exception_handler.py,sha256=_o7If47bzWLl57LeSXSWsIDsJGo2RIpwYAwNQ-hsHVY,2839
|
30
|
-
djresttoolkit-0.
|
31
|
-
djresttoolkit-0.
|
32
|
-
djresttoolkit-0.
|
33
|
-
djresttoolkit-0.
|
34
|
-
djresttoolkit-0.
|
32
|
+
djresttoolkit-0.7.0.dist-info/METADATA,sha256=k3gElJabHxN1l_dkMK0eld3Gt1W6QWofd2eyjT1-F_4,11357
|
33
|
+
djresttoolkit-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
34
|
+
djresttoolkit-0.7.0.dist-info/entry_points.txt,sha256=YMhfTF-7mYppO8QqqWnvR_hyMWvoYxD6XI94_ViFu3k,60
|
35
|
+
djresttoolkit-0.7.0.dist-info/licenses/LICENSE,sha256=8-oZM3yuuTRjySMbVKX9YXYA7Y4M_KhQNBYXPFjeWUo,1074
|
36
|
+
djresttoolkit-0.7.0.dist-info/RECORD,,
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import random
|
2
|
+
|
3
|
+
from pydantic import Field
|
4
|
+
|
5
|
+
|
6
|
+
def choice_field[T](choices: list[T]) -> T:
|
7
|
+
"""
|
8
|
+
Creates a field with a default value randomly selected from the provided choices.
|
9
|
+
Args:
|
10
|
+
choices (list[T]): A list of possible values for the field.
|
11
|
+
Returns:
|
12
|
+
T: A field with a default value randomly chosen from the given choices.
|
13
|
+
"""
|
14
|
+
|
15
|
+
return Field(
|
16
|
+
default_factory=lambda: random.choice(seq=choices),
|
17
|
+
)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from django.apps import apps
|
4
|
+
from django.core.management.base import BaseCommand, CommandError, CommandParser
|
5
|
+
from django.db import connection, transaction
|
6
|
+
|
7
|
+
|
8
|
+
class Command(BaseCommand):
|
9
|
+
help = "Flush database records for all models or a specific model"
|
10
|
+
|
11
|
+
def add_arguments(self, parser: CommandParser) -> None:
|
12
|
+
parser.add_argument(
|
13
|
+
"--model",
|
14
|
+
type=str,
|
15
|
+
help="Specify the model name to flush records (case-sensitive, e.g., User)",
|
16
|
+
)
|
17
|
+
parser.add_argument(
|
18
|
+
"--yes",
|
19
|
+
action="store_true",
|
20
|
+
help="Confirm flush without prompt",
|
21
|
+
)
|
22
|
+
|
23
|
+
def handle(self, *args: Any, **options: Any) -> None:
|
24
|
+
"""Handle the flushing of database records and reset IDs."""
|
25
|
+
|
26
|
+
model_name = options.get("model")
|
27
|
+
confirm = options.get("yes", False)
|
28
|
+
|
29
|
+
if not confirm:
|
30
|
+
prompt = "Are you sure you want to flush "
|
31
|
+
prompt += f"the model '{model_name}'" if model_name else "all models"
|
32
|
+
prompt += "? [y/n]: "
|
33
|
+
user_input = input(prompt)
|
34
|
+
if user_input.lower() not in ["y", "yes"]:
|
35
|
+
self.stdout.write(self.style.WARNING("Operation cancelled."))
|
36
|
+
return
|
37
|
+
|
38
|
+
def reset_sequence(table_name: str) -> None:
|
39
|
+
"""Reset auto-increment ID sequence for supported databases."""
|
40
|
+
with connection.cursor() as cursor:
|
41
|
+
if connection.vendor == "postgresql":
|
42
|
+
cursor.execute(
|
43
|
+
f'ALTER SEQUENCE "{table_name}_id_seq" RESTART WITH 1;'
|
44
|
+
)
|
45
|
+
elif connection.vendor == "sqlite":
|
46
|
+
cursor.execute(
|
47
|
+
f"DELETE FROM sqlite_sequence WHERE name='{table_name}';"
|
48
|
+
)
|
49
|
+
else:
|
50
|
+
self.stdout.write(
|
51
|
+
self.style.WARNING(
|
52
|
+
f"ID reset not implemented for {connection.vendor}."
|
53
|
+
)
|
54
|
+
)
|
55
|
+
|
56
|
+
if model_name:
|
57
|
+
# Find the model automatically across all apps
|
58
|
+
model = None
|
59
|
+
for m in apps.get_models():
|
60
|
+
if m.__name__ == model_name:
|
61
|
+
model = m
|
62
|
+
break
|
63
|
+
|
64
|
+
if not model:
|
65
|
+
raise CommandError(
|
66
|
+
f'Model "{model_name}" not found in any installed app.'
|
67
|
+
)
|
68
|
+
|
69
|
+
table_name = model._meta.db_table
|
70
|
+
with transaction.atomic():
|
71
|
+
deleted_count, _ = model.objects.all().delete()
|
72
|
+
reset_sequence(table_name)
|
73
|
+
|
74
|
+
self.stdout.write(
|
75
|
+
self.style.SUCCESS(
|
76
|
+
f'Flushed {deleted_count} records from model "{model_name}" and reset IDs.'
|
77
|
+
)
|
78
|
+
)
|
79
|
+
|
80
|
+
else:
|
81
|
+
# Flush all models
|
82
|
+
total_deleted = 0
|
83
|
+
with transaction.atomic():
|
84
|
+
for model in apps.get_models():
|
85
|
+
table_name = model._meta.db_table
|
86
|
+
deleted_count, _ = model.objects.all().delete()
|
87
|
+
total_deleted += deleted_count
|
88
|
+
reset_sequence(table_name)
|
89
|
+
|
90
|
+
self.stdout.write(
|
91
|
+
self.style.SUCCESS(
|
92
|
+
f"Flushed {total_deleted} records from all models and reset IDs."
|
93
|
+
)
|
94
|
+
)
|
File without changes
|
File without changes
|
File without changes
|