Skip to content

Commit 843674f

Browse files
authored
Merge pull request #6 from davidslusser/non_model_signals
adding support for user_login/user_logout signals
2 parents aa1e357 + fc1eba4 commit 843674f

File tree

25 files changed

+351
-131
lines changed

25 files changed

+351
-131
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,4 @@ dmypy.json
133133
*.iml
134134

135135

136-
signal_control_tests/local_test
136+
src/signal_control_tests/local_test

README.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# django-signalcontrol
2-
A django extension for dynamically enabling/disabling model-based signals.
2+
A django extension for dynamically enabling/disabling signals. This application allows django signals to be disabled or
3+
enabled on-demand through the django admin interface.
4+
35

46
| | |
57
|--------------|------|
68
| Author | David Slusser |
7-
| Description | A django extension for dynamically enabling/disabling model-based signals. |
9+
| Description | A django extension for dynamically enabling/disabling signals. |
810
| Requirements | `Python 3.x`<br>`Django 2.2.x` |
911

1012

@@ -22,20 +24,26 @@ Documentation source files are available in the docs folder.
2224
# Features
2325

2426
### signal decorator
27+
SignalControl can be added to a signal with the provided decorator. In the signals.py file, import the signalcontrol
28+
decorator and add the signal_control decorator to the line directly above the signal definition. Example:
2529

2630

2731
### admin interface
28-
32+
An django admin interface for django-signalcontrol is available to set signals to enabled or disabled. This displays
33+
all signals that can be controlled, and lists the application, model, signal receiver and signal name.
34+
Additionally, full search is available and filters are available for each field.
35+
Signals can be enabled or disabled individually or in bulk.
2936

3037

3138
# Usage Example
3239

33-
.. code-block:: python
40+
```python
41+
from signalcontrol.decorators import signal_control
3442

35-
@receiver(post_save, sender=MyCoolModel)
36-
@signal_control
37-
def msg_my_model_two(sender, instance, created, **kwargs):
38-
""" some signal """
39-
print("you just saved an instance of MyCoolModel")
43+
@receiver(post_save, sender=MyCoolModel)
44+
@signal_control
45+
def msg_after_my_model_save(sender, instance, created, **kwargs):
46+
""" some signal """
47+
print("you just saved an instance of MyCoolModel")
48+
```
4049

41-
..

docs/source/Stargate.png

-1.31 MB
Binary file not shown.

docs/source/about.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
About
55
=====
6-
django-signalcontrol is a reusable django application that adds dynamic control to model signals.
6+
django-signalcontrol is a reusable django application that adds dynamic control to signals.
77

88

9-
With signal_control added to a model signal, the signal can by enabled (default) or disabled from the django admin.
9+
With signal_control added to a signal, the signal can by enabled (default) or disabled from the django admin.
1010
An entry for the signal is added to the SignalControl table that includes a boolean field to enable/disable the signal.
1111
When a signal is disabled it will not execute when dispatched through the receiver, such as post_save.
1212

docs/source/features.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ This document details the features currently available in django-signalcontrol.
99

1010
Signal Detection
1111
----------------
12-
Model signals are detected automatically when django starts. Any model signal with signal_control applied will be
13-
detected and automatically added (if not already present) in the SignalControl database table. An info message will be
14-
printed when django starts if a new signal with signal_control is discovered. It will look like this:
12+
Signals are scanned automatically when django starts. Any signal with signal_control applied will be detected and
13+
automatically added (if not already present) in the SignalControl database table. An info message will be printed
14+
when django starts if a new signal with signal_control is discovered. It will look like this:
1515

16-
``INFO: registering msg_after_my_model_save in demo with SignalControl``
16+
``INFO: registering msg_after_my_model_save in my_app with SignalControl``
1717

18-
In this example, 'msg_after_my_model_save' is the name of the signal, and 'demo' is the name of the django app.
18+
In this example, 'msg_after_my_model_save' is the name of the signal, and 'my_app' is the name of the django app.
1919

2020

2121
The signal_control Decorator
2222
----------------------------
2323

24-
SignalControl can be added to a model signal via a provided decorator. In the signal.py file, import the signalcontrol
24+
SignalControl can be added to a signal with the provided decorator. In the signals.py file, import the signalcontrol
2525
decorator and add the signal_control decorator to the line directly above the signal definition. Example:
2626

2727
.. code-block:: python
@@ -40,8 +40,8 @@ decorator and add the signal_control decorator to the line directly above the si
4040
Admin Interface
4141
---------------
4242

43-
An django admin interface for django-signalcontrol is available to set model signals to enabled or disabled. This
44-
displays all model signals that can be controlled, and lists the application, model, signal receiver and signal name.
43+
An django admin interface for django-signalcontrol is available to set signals to enabled or disabled. This displays
44+
all model signals that can be controlled, and lists the application, model, signal receiver and signal name.
4545
Additionally, full search is available and filters are available for each field.
4646
Signals can be enabled or disabled individually or in bulk.
4747

docs/source/version_history.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Version History
88
:header: "Release", "Details"
99
:widths: 20, 100
1010

11+
"0.0.6", "adding support for user_logged_in/user_login_failed/user_logged_out signals"
1112
"0.0.5", "fixed bug causing OperationalError on migrate"
1213
"0.0.4", "project structure updates"
1314
"0.0.3", "bug fixes and code cleanup"

src/signal_control_tests/signal_control_tests/settings.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"""
1212

1313
import os
14+
import sys
1415

1516
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
1617
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -37,7 +38,9 @@
3738
'django.contrib.sessions',
3839
'django.contrib.messages',
3940
'django.contrib.staticfiles',
41+
'django_extensions',
4042
'signalcontrol',
43+
'test_app',
4144
]
4245

4346
MIDDLEWARE = [
@@ -119,3 +122,64 @@
119122
# https://docs.djangoproject.com/en/2.2/howto/static-files/
120123

121124
STATIC_URL = '/static/'
125+
126+
127+
128+
# LOGGING CONFIGURATION
129+
# ------------------------------------------------------------------------------
130+
LOG_PATH = "/Users/dslusser/code/django-signalcontrol/src/signal_control_tests/logs"
131+
if not os.path.join(LOG_PATH):
132+
os.mkdir(LOG_PATH)
133+
134+
LOGGING = {
135+
'version': 1,
136+
'disable_existing_loggers': False,
137+
'formatters': {
138+
'verbose': {
139+
'format': "[%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s",
140+
'datefmt': "%Y/%b/%d %H:%M:%S"
141+
},
142+
'simple': {
143+
'format': '%(levelname)s %(message)s'
144+
},
145+
},
146+
'handlers': {
147+
'django': {
148+
'level': 'DEBUG',
149+
'class': 'logging.handlers.RotatingFileHandler',
150+
'filename': '{}/django.log'.format(LOG_PATH),
151+
'maxBytes': 1024 * 1024 * 15,
152+
'backupCount': 10,
153+
'formatter': 'verbose',
154+
},
155+
'user': {
156+
'level': 'INFO',
157+
'class': 'logging.handlers.RotatingFileHandler',
158+
'filename': '{}/user.log'.format(LOG_PATH),
159+
'maxBytes': 1024 * 1024 * 15,
160+
'backupCount': 10,
161+
'formatter': 'verbose',
162+
},
163+
'console': {
164+
'level': 'INFO',
165+
'class': 'logging.StreamHandler',
166+
'stream': sys.stdout,
167+
'formatter': 'verbose',
168+
},
169+
170+
},
171+
'loggers': {
172+
'django': {
173+
'handlers': ['django', 'console'],
174+
'level': 'INFO',
175+
},
176+
'user': {
177+
'handlers': ['user', 'console'],
178+
'level': 'INFO',
179+
},
180+
'': {
181+
'handlers': ['console'],
182+
'level': 'INFO',
183+
}
184+
},
185+
}

src/signal_control_tests/signalcontrol/admin.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/signal_control_tests/signalcontrol/apps.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/signal_control_tests/signalcontrol/migrations/0001_initial.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/signal_control_tests/signalcontrol/migrations/__init__.py

Whitespace-only changes.

src/signal_control_tests/signalcontrol/models.py

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_app_config = 'test_app.apps.TestAppConfig'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.contrib import admin
2+
3+
# Register your models here.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.apps import AppConfig
2+
3+
4+
class TestAppConfig(AppConfig):
5+
name = 'test_app'
6+
7+
verbose_name = "test application for signalcontrol"
8+
9+
def ready(self):
10+
import test_app.signals
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generated by Django 2.2.12 on 2020-06-14 21:52
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='MyModelOne',
16+
fields=[
17+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('name', models.CharField(max_length=16)),
19+
],
20+
),
21+
migrations.CreateModel(
22+
name='MyModelThree',
23+
fields=[
24+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
25+
('name', models.CharField(max_length=16)),
26+
],
27+
),
28+
migrations.CreateModel(
29+
name='MyModelTwo',
30+
fields=[
31+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
32+
('name', models.CharField(max_length=16)),
33+
],
34+
),
35+
]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from django.db import models
2+
3+
4+
# Create your models here.
5+
class MyModelOne(models.Model):
6+
name = models.CharField(max_length=16)
7+
8+
9+
class MyModelTwo(models.Model):
10+
name = models.CharField(max_length=16)
11+
12+
13+
class MyModelThree(models.Model):
14+
name = models.CharField(max_length=16)

0 commit comments

Comments
 (0)