Package: edc-device
edc-deviceedc-deviceprovides device roles unique device IDs for hosts and clients where the hostname may not be reliable. Hosts can be group as servers, clients, node_servers and some of their functionality limited according to this role.A unique device ID is used to seed unique subject and sample identifiers. Uniqueness is evaluated during deployment.Device information is set in and read fromedc_device.apps.AppConfig.You should subclass into your projectsapps.pylike this, for example:fromedc_device.appsimportAppConfigasEdcDeviceAppConfigParentclassEdcDeviceAppConfig(EdcDeviceAppConfigParent):device_id='32'device_role=CLIENTdevice_permissions=DevicePermissions(plot_add,plot_change,...)and then in your settings:INSTALLED_APPS=[...my_app.apps.EdcDeviceAppConfig,myapp.apps.AppConfig',]Include in yoururls.py:urlpatterns=[...path('edc_device/',include('edc_device.urls')),...]To get to the Edc Device home page, reverse the url like this:reverse('edc_device:home_url')UsageAclientmight look like this:classEdcDeviceAppConfig(EdcDeviceAppConfigParent):device_id='18'node_server_id_list=[97,98,99]middleman_id_list=[95,96]>>>fromdjango.appsimportappsasdjango_apps>>>app_config=django_apps.get_app_config('edc_device')>>>app_config.device_id'18'>>>app_config.is_clientTrue>>>app_config.device_role'Client'A node server server might look like this:classEdcDeviceAppConfig(EdcDeviceAppConfigParent):device_id='98'node_server_id_list=[97,98,99]middleman_id_list=[95,96]>>>fromdjango.appsimportappsasdjango_apps>>>app_config=django_apps.get_app_config('edc_device')>>>app_config.device_id'98'>>>app_config.is_node_serverTrue>>>app_config.device_role'NodeServer'A middleman server might look like this:classEdcDeviceAppConfig(EdcDeviceAppConfigParent):device_id='95'node_server_id_list=[97,98,99]middleman_id_list=[95,96]>>>fromdjango.appsimportappsasdjango_apps>>>app_config=django_apps.get_app_config('edc_device')>>>app_config.device_id'95'>>>app_config.is_middlemanTrue>>>app_config.device_role'Middleman'The central server might look like this:classEdcDeviceAppConfig(EdcDeviceAppConfigParent):device_id='99'node_server_id_list=[97,98,99]middleman_id_list=[95,96]>>>fromdjango.appsimportappsasdjango_apps>>>app_config=django_apps.get_app_config('edc_device')>>>app_config.device_id'99'>>>app_config.is_middlemanTrue>>>app_config.device_role'CentralServer'See alsodjango-collect-offline.Device Permissions by ModelYou can use the device role, or the device ID, to limit ADD/CHANGE permissions on a model.edc-deviceAppConfig maintains a collection ofDeviceAddPermissionandDeviceChangePermissioninstances that are inspected in thesavemethod of a model using theDeviceModelMixin.To declare aDeviceAddPermissionobject:test_model_add=DeviceAddPermission(model='my_app.mymodel, device_roles=[NODE_SERVER, CENTRAL_SERVER])To declare aDeviceChangePermissionobject:test_model_change=DeviceChangePermission(model='my_app.mymodel, device_roles=[CLIENT])This means that ifapp_config.device_roleis anything other thanNODE_SERVERorCENTRAL_SERVER, the save method will raise aDevicePermissionsAddError.To register the instances withedc_device.apps.AppConfig.device_permissions:device_permissions=DevicePermissions(test_model_add,test_model_change)This means that ifapp_config.device_roleis anything other thanCLIENT, the save method will raise aDevicePermissionsChangeError.On boot up you should see:LoadingEdcDevice...*deviceidis'10'.*deviceroleis'Client'.*devicepermissionsexistfor:-edc_device.testmodelADDNodeServer,CentralServer-edc_device.testmodelCHANGEClientDoneloadingEdcDevice.Models declared with theEdcDeviceModelMixincheck the device permissions collection on save. Note the model mixin is already declared withBaseUuidModel.fromedc_model.modelsimportBaseUuidModelclassTestModel(BaseUuidModel):passDeclaring device permissions directly on modelMetaclass:You can declare device permissions onMeta.device_permissionsin the same way as above.[...]classMeta(DeviceModelMixin.Meta):device_permissions=DevicePermissions(...)BothMetaandAppConfigdevice permissions will be called, where theMetaclass object will be called first.Disable device permissions by model instance:You can disable device permissionsper model instanceby settingcheck_device_permissionstoFalseCustomizing Device PermissionsThe ADD and CHANGE device permission objects by default inspect the model’sid. Ifobj.idisNone, it as an ADD model operation; Ifobj.idis notNone, it is a CHANGE model operation.You can change this by overriding themodel_operationmethod. Themodel_operationmust returnNoneor some value, such asself.label.For example:# default for DeviceAddPermissionlabel='ADD'defmodel_operation(self,model_obj=None,**kwargs):ifnotmodel_obj.id:returnself.labelreturnNone# overriddendefmodel_operation(self,model_obj=None,**kwargs):"""Return ADD if both id and plot identifier are None.
    """ifnotmodel_obj.idandnotobj.plot_identifier:returnself.labelreturnNone