Setting up pyenv and show default value on confirm add (#7)

Co-authored-by: Thu Trang Pham <thu@joinmodernhealth.com>
main
Thu Trang Pham 2021-02-09 17:03:18 -08:00 committed by GitHub
parent 591aa48ba0
commit 209de62c9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 219 additions and 23 deletions

1
.python-version 100644
View File

@ -0,0 +1 @@
django-admin-confirm-3.8

View File

@ -5,7 +5,6 @@ test:
coverage run --branch -m pytest coverage run --branch -m pytest
coverage html coverage html
coverage-badge -f -o coverage.svg coverage-badge -f -o coverage.svg
python -m readme_renderer README.md -o /tmp/README.html
check-readme: check-readme:
python -m readme_renderer README.md -o /tmp/README.html python -m readme_renderer README.md -o /tmp/README.html

View File

@ -6,6 +6,8 @@ AdminConfirmMixin is a mixin for ModelAdmin to add confirmations to change, add
![Screenshot of Change Confirmation Page](https://raw.githubusercontent.com/TrangPham/django-admin-confirm/32192d3988a9bd44c734a66baff91f02dd28136b/screenshot.png) ![Screenshot of Change Confirmation Page](https://raw.githubusercontent.com/TrangPham/django-admin-confirm/32192d3988a9bd44c734a66baff91f02dd28136b/screenshot.png)
![Screenshot of Add Confirmation Page](https://raw.githubusercontent.com/TrangPham/django-admin-confirm/32192d3988a9bd44c734a66baff91f02dd28136b/screenshot_confirm_add.png)
![Screenshot of Action Confirmation Page](https://raw.githubusercontent.com/TrangPham/django-admin-confirm/264900a21658cc979dd2026038db73f8a1b73c64/screenshot_confirm_action.png) ![Screenshot of Action Confirmation Page](https://raw.githubusercontent.com/TrangPham/django-admin-confirm/264900a21658cc979dd2026038db73f8a1b73c64/screenshot_confirm_action.png)
It can be configured to add a confirmation page on ModelAdmin upon: It can be configured to add a confirmation page on ModelAdmin upon:
@ -126,6 +128,38 @@ Your appreciation is also very welcome :) Feel free to:
- star the project - star the project
- open an issue just to share your thanks - open an issue just to share your thanks
### Local Development Setup
Install pyenv
Install python 3.8
Create virtualenv via pyenv
```
pyenv vituralenv 3.8 django-admin-confirm-3.8
```
Now your terminal should have `(django-admin-confirm-3.8)` prefix, because `.python-version` should have auto switch your virtual env
Run migrations and create a superuser and run the server
```
./tests/manage.py migrate
./tests/manage.py createsuperuser
./tests/manage.py runserver
```
You should be able to see the test app at `localhost:8000/admin`
Running tests:
```
make test
tox
```
Testing new changes on test project:
## Feature List ## Feature List
This is a list of features which could potentially be added in the future. Some of which might make more sense in their own package. This is a list of features which could potentially be added in the future. Some of which might make more sense in their own package.

View File

@ -134,14 +134,16 @@ class AdminConfirmMixin:
changed_data = {} changed_data = {}
if form_validated: if form_validated:
if add: if add:
for name in form.changed_data: for name in form.cleaned_data:
new_value = getattr(new_object, name) new_value = getattr(new_object, name)
# Don't consider default values as changed for adding # Don't consider default values as changed for adding
default_value = model._meta.get_field(name).get_default()
if ( if (
new_value is not None new_value is not None
and new_value != model._meta.get_field(name).default and new_value != default_value
): ):
changed_data[name] = [None, new_value] # Show what the default value is
changed_data[name] = [str(default_value), new_value]
else: else:
# Parse the changed data - Note that using form.changed_data would not work because initial is not set # Parse the changed data - Note that using form.changed_data would not work because initial is not set
for name, field in form.fields.items(): for name, field in form.fields.items():

View File

@ -1,11 +1,19 @@
{% if changed_data %} {% if changed_data %}
<div class="changed-data"> <div class="changed-data">
<p><b>Confirm Values:</b></p> <p><b>Confirm Values:</b></p>
<table> <table>
<tr><th>Field</th><th>Current Value</th><th>New Value</th></tr> <tr>
{% for field, values in changed_data.items %} <th>Field</th>
<tr><td>{{ field }}</td><td>{{ values.0 }}</td><td>{{ values.1 }}</td></tr> <th>{% if add %} Default {% else %} Current {% endif %}Value</th>
{% endfor %} <th>New Value</th>
</table> </tr>
</div> {% for field, values in changed_data.items %}
<tr>
<td>{{ field }}</td>
<td>{{ values.0 }}</td>
<td>{{ values.1 }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endif %} {% endif %}

View File

@ -9,13 +9,13 @@
</mask> </mask>
<g mask="url(#a)"> <g mask="url(#a)">
<path fill="#555" d="M0 0h63v20H0z"/> <path fill="#555" d="M0 0h63v20H0z"/>
<path fill="#4c1" d="M63 0h36v20H63z"/> <path fill="#fe7d37" d="M63 0h36v20H63z"/>
<path fill="url(#b)" d="M0 0h99v20H0z"/> <path fill="url(#b)" d="M0 0h99v20H0z"/>
</g> </g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="31.5" y="14">coverage</text> <text x="31.5" y="14">coverage</text>
<text x="80" y="15" fill="#010101" fill-opacity=".3">100%</text> <text x="80" y="15" fill="#010101" fill-opacity=".3">42%</text>
<text x="80" y="14">100%</text> <text x="80" y="14">42%</text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 903 B

After

Width:  |  Height:  |  Size: 904 B

View File

@ -1,4 +1,4 @@
[pytest] [pytest]
DJANGO_SETTINGS_MODULE=tests.test_project.settings DJANGO_SETTINGS_MODULE=tests.test_project.settings.test
addopts = --doctest-modules -ra -l --tb=short --show-capture=log --color=yes addopts = --doctest-modules -ra -l --tb=short --show-capture=log --color=yes
testpaths = admin_confirm testpaths = admin_confirm

View File

@ -1,2 +1,10 @@
Django>=1.7.0 Django>=1.7.0
factory-boy~=3.0.1 factory-boy~=3.0.1
django-admin-confirm~=0.2.1
coverage~=5.4
pytest~=6.2.2
tox~=3.21.4
pytest-django~=4.1.0
coverage-badge~=1.0.1
readme-renderer~=28.0
twine~=3.3.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -25,5 +25,4 @@ setup(
# ISSUE-4: Ensure that package includes template and css folders # ISSUE-4: Ensure that package includes template and css folders
# list files in MANIFEST.in # list files in MANIFEST.in
include_package_data=True, include_package_data=True,
) )

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.6 on 2021-02-10 00:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('market', '0003_auto_20201108_1717'),
]
operations = [
migrations.AddField(
model_name='inventory',
name='notes',
field=models.TextField(blank=True, default='This is the default', null=True),
),
]

View File

@ -32,3 +32,4 @@ class Inventory(models.Model):
) )
item = models.ForeignKey(to=Item, on_delete=models.CASCADE) item = models.ForeignKey(to=Item, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=0, null=True, blank=True) quantity = models.PositiveIntegerField(default=0, null=True, blank=True)
notes = models.TextField(default="This is the default", null=True, blank=True)

View File

@ -37,7 +37,7 @@ INSTALLED_APPS = [
"django.contrib.sessions", "django.contrib.sessions",
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"tests.market", "market",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -50,7 +50,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
] ]
ROOT_URLCONF = "tests.test_project.urls" ROOT_URLCONF = "test_project.urls"
TEMPLATES = [ TEMPLATES = [
{ {
@ -68,7 +68,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = "tests.test_project.wsgi.application" WSGI_APPLICATION = "test_project.wsgi.application"
# Database # Database

View File

@ -0,0 +1 @@
from .local import *

View File

@ -0,0 +1,115 @@
"""
Django settings for test_project project.
Generated by 'django-admin startproject' using Django 3.0.10.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "=yddl-40388w3e2hl$e8)revce=n67_idi8pfejtn3!+2%!_qt"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
# Application definition
INSTALLED_APPS = [
"admin_confirm",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = "/static/"

View File

@ -0,0 +1,5 @@
from .base import *
INSTALLED_APPS = INSTALLED_APPS + ['market']
WSGI_APPLICATION = "test_project.wsgi.application"
ROOT_URLCONF = "test_project.urls"

View File

@ -0,0 +1,5 @@
from .base import *
INSTALLED_APPS = INSTALLED_APPS + ['tests.market']
WSGI_APPLICATION = "tests.test_project.wsgi.application"
ROOT_URLCONF = "tests.test_project.urls"