Base mixins and utilities for clinicedc/edc projects.
Project description
[![Build Status](https://travis-ci.org/clinicedc/edc-base.svg?branch=develop)](https://travis-ci.org/clinicedc/edc-base)
[![Coverage Status](https://coveralls.io/repos/clinicedc/edc-base/badge.svg?branch=develop&service=github)](https://coveralls.io/github/clinicedc/edc-base?branch=develop)
# edc-base
Base model, manager, field, form and admin classes for Edc.
Installation
------------
In the __settings__ file add:
STUDY_OPEN_DATETIME = datetime.today()
STUDY_CLOSE_DATETIME = datetime.today()
GENDER_OF_CONSENT = ['M', 'F']
Optional __settings__ attributes:
# phone number validtors
# the default is '^[0-9+\(\)#\.\s\/ext-]+$'
TELEPHONE_REGEX = '^[2-8]{1}[0-9]{6}$'
CELLPHONE_REGEX = '^[7]{1}[12345678]{1}[0-9]{6}$',
### ModelForm Mixin
#### CommonCleanModelFormMixin
Works together with `common_clean` on the model that inherits from `BaseModel`.
The validation logic lives on the model but can be called in time for the ModelForm.clean() to re-raise the exceptions and place the error messages on the ModelForm page.
If the exception instance has a second `arg` it will be used as the form field name and the error message will be placed by the field on the page.
For example:
On the model you must use `BaseModel`:
from edc_base.model.models import BaseModel
class MyModel(BaseModel, models.Model):
f1 = models.CharField(...)
f2 = models.CharField(...)
def common_clean(self):
# note: (1) this code should be validation code. Avoid setting any field attributes here.
# (2) this method will be called in the model save method as well.
if f1 != 'happiness':
raise ExceptionOne('Expected happiness.', 'f1')
if f2 != 'liberty':
raise ExceptionTwo('Expected liberty.', 'f2')
super().common_clean()
@property
def common_clean_exceptions(self):
common_clean_exceptions = super().common_clean_exceptions
common_clean_exceptions.extend([ExceptionOne, ExceptionTwo])
return common_clean_exceptions
On the ModelForm, just add the mixin. If you do override `clean()` be sure to call `super()`.
from edc_base.form_mixins import CommonCleanModelFormMixin
MyModelForm(CommonCleanModelFormMixin, for.ModelForm):
def clean(self):
cleaned_data = super().clean()
...
...
...
return cleaned_data
### Model Field Validators
__CompareNumbersValidator:__ Compare the field value to a static value. For example, validate that the
age of consent is between 18 and 64.
consent_age = models.IntegerField(
validators=[
CompareNumbersValidator(18, '>=', message='Age of consent must be {}. Got {}'),
CompareNumbersValidator(64, '<=', message='Age of consent must be {}. Got {}')
]
Or you can use the special validators `MinConsentAgeValidator`, `MaxConsentAgeValidator`:
consent_age = models.IntegerField(
validators=[
MinConsentAgeValidator(18),
MaxConsentAgeValidator(64)
]
### Audit trail (HistoricalRecord):
(in development PY3/DJ1.8+)
HistoricalRecord is an almost identical version of `simple_history.models.HistoricalRecord`
with the exception of two methods: `get_extra_fields()` and `add_extra_methods()`. Method
`get_extra_fields()` method is overridden to change the *history_id* primary key from an
`IntegerField` to a `UUIDField` so that it can work with module `django_offline`.
from edc_base.model.models import HistoricalRecord
class MyModel(BaseUuidModel):
...
history = HistoricalRecord()
class Meta:
app_label = 'my_app'
The audit trail models created by `simple_history` have a foreign key to `auth.User`.
In order for the models to work with `django_offline` specify the django_offline User model in settings:
AUTH_USER_MODEL = 'django_offline.User'
### Notes
User created and modified fields behave as follows:
* created is only set on pre-save add
* modified is always updated
[![Coverage Status](https://coveralls.io/repos/clinicedc/edc-base/badge.svg?branch=develop&service=github)](https://coveralls.io/github/clinicedc/edc-base?branch=develop)
# edc-base
Base model, manager, field, form and admin classes for Edc.
Installation
------------
In the __settings__ file add:
STUDY_OPEN_DATETIME = datetime.today()
STUDY_CLOSE_DATETIME = datetime.today()
GENDER_OF_CONSENT = ['M', 'F']
Optional __settings__ attributes:
# phone number validtors
# the default is '^[0-9+\(\)#\.\s\/ext-]+$'
TELEPHONE_REGEX = '^[2-8]{1}[0-9]{6}$'
CELLPHONE_REGEX = '^[7]{1}[12345678]{1}[0-9]{6}$',
### ModelForm Mixin
#### CommonCleanModelFormMixin
Works together with `common_clean` on the model that inherits from `BaseModel`.
The validation logic lives on the model but can be called in time for the ModelForm.clean() to re-raise the exceptions and place the error messages on the ModelForm page.
If the exception instance has a second `arg` it will be used as the form field name and the error message will be placed by the field on the page.
For example:
On the model you must use `BaseModel`:
from edc_base.model.models import BaseModel
class MyModel(BaseModel, models.Model):
f1 = models.CharField(...)
f2 = models.CharField(...)
def common_clean(self):
# note: (1) this code should be validation code. Avoid setting any field attributes here.
# (2) this method will be called in the model save method as well.
if f1 != 'happiness':
raise ExceptionOne('Expected happiness.', 'f1')
if f2 != 'liberty':
raise ExceptionTwo('Expected liberty.', 'f2')
super().common_clean()
@property
def common_clean_exceptions(self):
common_clean_exceptions = super().common_clean_exceptions
common_clean_exceptions.extend([ExceptionOne, ExceptionTwo])
return common_clean_exceptions
On the ModelForm, just add the mixin. If you do override `clean()` be sure to call `super()`.
from edc_base.form_mixins import CommonCleanModelFormMixin
MyModelForm(CommonCleanModelFormMixin, for.ModelForm):
def clean(self):
cleaned_data = super().clean()
...
...
...
return cleaned_data
### Model Field Validators
__CompareNumbersValidator:__ Compare the field value to a static value. For example, validate that the
age of consent is between 18 and 64.
consent_age = models.IntegerField(
validators=[
CompareNumbersValidator(18, '>=', message='Age of consent must be {}. Got {}'),
CompareNumbersValidator(64, '<=', message='Age of consent must be {}. Got {}')
]
Or you can use the special validators `MinConsentAgeValidator`, `MaxConsentAgeValidator`:
consent_age = models.IntegerField(
validators=[
MinConsentAgeValidator(18),
MaxConsentAgeValidator(64)
]
### Audit trail (HistoricalRecord):
(in development PY3/DJ1.8+)
HistoricalRecord is an almost identical version of `simple_history.models.HistoricalRecord`
with the exception of two methods: `get_extra_fields()` and `add_extra_methods()`. Method
`get_extra_fields()` method is overridden to change the *history_id* primary key from an
`IntegerField` to a `UUIDField` so that it can work with module `django_offline`.
from edc_base.model.models import HistoricalRecord
class MyModel(BaseUuidModel):
...
history = HistoricalRecord()
class Meta:
app_label = 'my_app'
The audit trail models created by `simple_history` have a foreign key to `auth.User`.
In order for the models to work with `django_offline` specify the django_offline User model in settings:
AUTH_USER_MODEL = 'django_offline.User'
### Notes
User created and modified fields behave as follows:
* created is only set on pre-save add
* modified is always updated
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file edc-base-0.2.22.macosx-10.13-x86_64.tar.gz
.
File metadata
- Download URL: edc-base-0.2.22.macosx-10.13-x86_64.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 16a0f18286d24ad201ee3e72fcb34efc865f0190f6140b48ea3ceb44f8e74062 |
|
MD5 | 6fac9da9c7017897b8fb020ac8c03d12 |
|
BLAKE2b-256 | c860565774c9bda32a031d3e7adba0ae7f9b77167bca89cf3ff292788e699387 |
File details
Details for the file edc_base-0.2.22-py3-none-any.whl
.
File metadata
- Download URL: edc_base-0.2.22-py3-none-any.whl
- Upload date:
- Size: 1.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ba9cf605bfb278995c32f5112145bf72d580b6f2c4777fc3c5279a20b8b360fe |
|
MD5 | 689798d9f34c939db84828ac833f4f9a |
|
BLAKE2b-256 | a582b9d45c835fbb96312d0896ba0ac7f6b0e83beac031f5774b06a5c6d250b0 |