Coverage for gws-app/gws/base/model/__init__.py: 0%

3 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1"""Data models. 

2 

3A data model, or simply model, is an object that deals with features from 

4external sources, like database tables, shape files, GML responses, etc. The 

5mission of a model is to read features from the source and convert them to a form 

6suitable for client representation. An "editable" model can also accept features 

7back from the client, parse, validate and store them. 

8 

9Features 

10-------- 

11 

12A feature is a collection of named attributes. One of these attributes can 

13act as a unique ID (``uid``), and another one can be the feature 

14geometry (``shape``). ``uid`` is required for editable models, ``shape`` is always optional. 

15 

16There are three kinds of objects that represent Features: 

17 

18The feature object (`gws.Feature`) is an internal representation of a 

19Feature. It provides storage for attributes and convenience methods to extract 

20or mutate them. A feature also contains a list of ``views``, which are chunks of HTML, 

21rendered by templates and used to represent a feature in the client. 

22 

23A record object (`gws.FeatureRecord`) is a data object that only contains a 

24dict of attributes and, optionally, some metadata properties, depending on the 

25source. For example, GML feature records usually contain the layer name. It 

26represents raw source data. 

27 

28A props object (`gws.FeatureProps`) contains data necessary to display a feature 

29in the client. When viewing features, the client only needs their ``uid``, ``shape`` and 

30``views``. In the edit context, the props object also contains a dict of attributes. 

31 

32Operation modes 

33--------------- 

34 

35Models are used to perform several abstract operations: 

36 

37- ``read`` - the client provides a search query (`gws.Search`) and expects a list of matching Props 

38- ``init`` - the client requests a new empty Feature to be initialized and sent back 

39- ``create`` - the client sends feature props and wants to create new features in the source 

40- ``update`` - the client sends feature props and wants to update existing features 

41- ``delete`` - the client sends feature props and wants respective features to be deleted 

42 

43Fields 

44------ 

45 

46Most models contain a collection of field objects (`gws.ModelField`). A field 

47deals with a subset of feature data and can convert it between representations 

48and validate it. 

49 

50When a model performs an operation, it is delegated to all its fields in turn. 

51 

52A model without fields, called "ad-hoc" or "default" model, can only perform "view" operations. 

53It simply copies attributes between props and records. 

54 

55There are two types of fields: "scalar" Fields represent one or multiple 

56attributes (columns) in the source itself, and "related" fields represent 

57features from other models, linked to the current model. 

58 

59Values 

60------ 

61 

62A field can have "value" (`gws.ModelValue`) objects attached to it. 

63Value objects provide a ``compute`` method. When a model performs an operation, 

64and a field has a value object configured for this operation, its ``compute`` method 

65is called, and the returned value is used as a field's value. 

66 

67Validators 

68---------- 

69 

70A field can also have "validator" (`gws.ModelValidator`) objects attached. When 

71performing ``create`` and ``update`` operations, the model ensures that all 

72configured validators return ``True``. 

73 

74 

75Permissions 

76----------- 

77 

78To perform a model operation, the user must have a permission to do so. 

79The permissions (`gws.Access`) are interpreted as follows: 

80 

81- ``read`` - can perform ``read`` operation 

82- ``write`` - can perform ``read`` and ``update`` 

83- ``create`` - can perform ``read``, ``init`` and ``create`` 

84- ``delete`` - can perform ``read`` and ``delete`` 

85 

86It is an error to perform a model operation without permission. 

87 

88Each Field can also have permissions, interpreted as follows: 

89 

90- ``read`` - the content of the field can be read from the source 

91- ``write`` - user input for this field can be written to the source 

92 

93It is *not* an error to attempt to read or write a field without permission. 

94The attempt is just silently ignored. 

95 

96Field "read" permissions are applied when a feature is converted to props, 

97"write" permissions - when it is converted to a record. 

98 

99If a field has attached value objects, these are applied regardless of field permissions. 

100 

101Context 

102------- 

103 

104All model operation require a context data object (`gws.ModelContext`), usually called ``mc``. This object contains: 

105 

106- the operation (``read``, ``update`` etc) 

107- user performing the operation 

108- current project 

109- other properties, mostly database related 

110 

111Models provide methods to perform operations, while fields contain callback methods, invoked by a model. 

112 

113For example, here's an implementation of the ``update`` operation:: 

114 

115 

116 class Model 

117 

118 def update_feature (feature, mc) 

119 

120 check if mc.user is allowed to write to this model 

121 

122 attach an empty record to feature 

123 

124 open a transaction in the Source 

125 

126 for each field in this model 

127 invoke "before_update" callback 

128 to transfer data from feature.attributes to feature.record 

129 

130 write changes to the source, using feature.uid as a key and feature.record as data 

131 (e.g. UPDATE source SET ...record... WHERE id=feature.uid) 

132 

133 for each field in this model 

134 invoke "after_update" callback for each field 

135 to synchronize updated data, e.g. update a linked model 

136 

137 commit the transaction 

138 

139""" 

140 

141from .core import Config, Object, Props 

142 

143from . import manager, default_model, util, field, related_field 

144 

145from .util import ( 

146 iter_features, 

147 secondary_context, 

148)