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
Close
Hashes for edc-base-0.2.22.macosx-10.13-x86_64.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 16a0f18286d24ad201ee3e72fcb34efc865f0190f6140b48ea3ceb44f8e74062 |
|
MD5 | 6fac9da9c7017897b8fb020ac8c03d12 |
|
BLAKE2b-256 | c860565774c9bda32a031d3e7adba0ae7f9b77167bca89cf3ff292788e699387 |
Close
Hashes for edc_base-0.2.22-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ba9cf605bfb278995c32f5112145bf72d580b6f2c4777fc3c5279a20b8b360fe |
|
MD5 | 689798d9f34c939db84828ac833f4f9a |
|
BLAKE2b-256 | a582b9d45c835fbb96312d0896ba0ac7f6b0e83beac031f5774b06a5c6d250b0 |