Documentation
¶
Index ¶
- Constants
- Variables
- func CastToNumber[T any](v any) (T, error)
- func FieldNames(d any, exclude []string) []string
- func ForceSet(d Definer, name string, value interface{}) error
- func Get[T any](d Definer, name string) T
- func InterfaceList[T any](list []T) []any
- func IsModelRegistered(model Definer) bool
- func Method[T any](obj interface{}, name string) (n T, ok bool)
- func PrimaryKey(d Definer) interface{}
- func RegisterDefaultType(valueOfType any, ...)
- func RegisterFormFieldType(valueOfType any, getField func(opts ...func(fields.Field)) fields.Field)
- func RegisterModel(model Definer)
- func Set(d Definer, name string, value interface{}) error
- func SetMany(d Definer, values map[string]interface{}) error
- func SetPrimaryKey(d Definer, value interface{}) error
- func StoreOnMeta(m Definer, key string, value any)
- func ToString(v any) string
- type CanModelInfo
- type CanRelatedName
- type DefaultGetter
- type Definer
- type Definitions
- type Field
- type FieldConfig
- type FieldDef
- func (f *FieldDef) AllowBlank() bool
- func (f *FieldDef) AllowEdit() bool
- func (f *FieldDef) AllowNull() bool
- func (f *FieldDef) Attrs() map[string]interface{}
- func (f *FieldDef) ColumnName() string
- func (f *FieldDef) FormField() fields.Field
- func (f *FieldDef) GetDefault() interface{}
- func (f *FieldDef) GetValue() interface{}
- func (f *FieldDef) HelpText() string
- func (f *FieldDef) Instance() Definer
- func (f *FieldDef) IsPrimary() bool
- func (f *FieldDef) Label() string
- func (f *FieldDef) Name() string
- func (f *FieldDef) Rel() Relation
- func (f *FieldDef) Scan(value any) error
- func (f *FieldDef) SetValue(v interface{}, force bool) error
- func (f *FieldDef) Tag(name string) string
- func (f *FieldDef) ToString() string
- func (f *FieldDef) Type() reflect.Type
- func (f *FieldDef) Validate() error
- func (f *FieldDef) Value() (driver.Value, error)
- type FieldDefinition
- type FormFieldGetter
- type Helper
- type Labeler
- type ModelMeta
- type ObjectDefinitions
- func (d *ObjectDefinitions) Field(name string) (f Field, ok bool)
- func (d *ObjectDefinitions) Fields() []Field
- func (d *ObjectDefinitions) ForceSet(name string, value interface{}) error
- func (d *ObjectDefinitions) Get(name string) interface{}
- func (d *ObjectDefinitions) Instance() Definer
- func (d *ObjectDefinitions) Len() int
- func (d *ObjectDefinitions) Primary() Field
- func (d *ObjectDefinitions) Set(name string, value interface{}) error
- func (d *ObjectDefinitions) TableName() string
- func (d *ObjectDefinitions) WithTableName(name string) *ObjectDefinitions
- type PathMetaChain
- type Relation
- type RelationTarget
- type RelationType
- type Scanner
- type StaticDefinitions
- type Through
- type ThroughModel
Constants ¶
const ( // AttrNameKey (string) is the name of the field. AttrNameKey = "field.name" // AttrMaxLengthKey (int64) is the maximum length of the field. AttrMaxLengthKey = "field.max_length" // AttrMinLengthKey (int64) is the minimum length of the field. AttrMinLengthKey = "field.min_length" // AttrMinValueKey (float64) is the minimum value of the field. AttrMinValueKey = "field.min_value" // AttrMaxValueKey (float64) is the maximum value of the field. AttrMaxValueKey = "field.max_value" // AttrAllowNullKey (bool) is whether the field allows null values. AttrAllowNullKey = "field.allow_null" // AttrAllowBlankKey (bool) is whether the field allows blank values. AttrAllowBlankKey = "field.allow_blank" // AttrAllowEditKey (bool) is whether the field is read-only. AttrAllowEditKey = "field.read_only" // AttrIsPrimaryKey (bool) is whether the field is a primary key. AttrIsPrimaryKey = "field.primary" // AttrAutoIncrementKey (bool) is whether the field is an auto-incrementing field. AttrAutoIncrementKey = "field.auto_increment" // AttrUniqueKey (bool) is whether the field is a unique field. AttrUniqueKey = "field.unique" // AttrReverseAliasKey (string) is the reverse alias of the field. AttrReverseAliasKey = "field.reverse_alias" )
Keys of attributes defined with the `Attrs()` method on fields.
These are used to store extra information about the field.
We provide some default keys which might be useful for implementing an ORM, but any keys can be used.
const ( HookFormFieldForType = "attrs.FormFieldForType" DefaultForType = "attrs.DefaultForType" )
const ATTR_TAG_NAME = "attrs"
Variables ¶
var ( // A signal that is called before a model is registered. // // This can be used to add custom logic before a model is registered. OnBeforeModelRegister = modelSignalPool.Get("attrs.OnBeforeModelRegister") // A signal that is called after a model is registered. // // This can be used to add custom logic after a model is registered. OnModelRegister = modelSignalPool.Get("attrs.OnModelRegister") )
The following signals are available for hooking into the `attrs` package's model registration process.
It can be hooked into to add custom logic before a model is registered.
Example usage:
func init() { attrs.OnBeforeModelRegister.Listen(func(s signals.Signal[attrs.Definer], obj attrs.Definer) error { // Do something before the model is registered return nil }) }
var ( ErrEmptyString = errors.New("empty string") ErrConvertingString = errors.New("error converting string to number") )
Functions ¶
func CastToNumber ¶ added in v1.7.0
CastToNumber converts a value of any type (int, float, string) to a number of type T. It returns the converted value and an error if the conversion fails.
func FieldNames ¶
A shortcut for getting the names of all fields in a Definer.
The exclude parameter can be used to exclude certain fields from the result.
This function is useful when you need to get the names of all fields in a model, but you want to exclude certain fields (e.g. fields that are not editable).
func ForceSet ¶
ForceSet sets the value of a field on a Definer.
If the field is not found, the value is not of the correct type or another constraint is violated, this function will panic.
This function will allow setting the value of a field that is marked as not editable.
func Get ¶
Get retrieves the value of a field on a Definer.
If the field is not found, this function will panic.
Type assertions are used to ensure that the value is of the correct type, as well as providing less work for the caller.
func InterfaceList ¶ added in v1.7.0
InterfaceList converts a slice of []T to []any.
func IsModelRegistered ¶ added in v1.7.0
func Method ¶
Method retrieves a method from an object.
The generic type parameter must be the type of the method.
func PrimaryKey ¶ added in v1.6.6
func PrimaryKey(d Definer) interface{}
PrimaryKey returns the primary key field of a Definer.
If the primary key field is not found, this function will panic.
func RegisterDefaultType ¶ added in v1.7.0
func RegisterDefaultType(valueOfType any, getDefault func(f Field, new_field_t_indirected reflect.Type, field_v reflect.Value) (interface{}, bool))
RegisterDefaultType registers a default value to be used for that specific type.
This is useful when implementing custom types.
Example usage:
RegisterDefaultType( json.RawMessage{}, func(f Field, new_field_t_indirected reflect.Type, field_v reflect.Value) (interface{}, bool) { if field_v.IsValid() && field_v.Type() == reflect.TypeOf(json.RawMessage{}) { return json.RawMessage{}, true } return nil, false }, )
func RegisterFormFieldType ¶
RegisterFormFieldType registers a field type for a given valueOfType.
getField is a function that returns a fields.Field for the given valueOfType.
The valueOfType can be a reflect.Type or any value, in which case the reflect.TypeOf(valueOfType) will be used.
This is a shortcut function for the `HookFormFieldForType` hook.
Example usage:
RegisterFormFieldType( json.RawMessage{}, func(opts ...func(fields.Field)) fields.Field { return fields.JSONField[json.RawMessage](opts...) }, )
func RegisterModel ¶ added in v1.7.0
func RegisterModel(model Definer)
RegisterModel registers a model to be used for any ORM- type operations.
Models are registered automatically in [django.Initialize], but you can also register them manually if needed.
func Set ¶
Set sets the value of a field on a Definer.
If the field is not found, the value is not of the correct type or another constraint is violated, this function will panic.
If the field is marked as non editable, this function will panic.
func SetMany ¶
SetMany sets multiple fields on a Definer.
The values parameter is a map where the keys are the names of the fields to set.
The values must be of the correct type for the fields.
func SetPrimaryKey ¶ added in v1.7.0
SetPrimaryKey sets the primary key field of a Definer.
If the primary key field is not found, this function will panic.
func StoreOnMeta ¶ added in v1.7.0
func ToString ¶
ToString converts a value to a string.
This should be the human-readable representation of the value.
If the value is a struct with a content type, it will use the content type's InstanceLabel method to convert it to a string.
time.Time, mail.Address, and error types are handled specially.
If the value is a slice or array, it will convert each element to a string and join them with ", ".
If all else fails, it will use fmt.Sprintf to convert the value to a string.
Types ¶
type CanModelInfo ¶ added in v1.7.0
type CanModelInfo interface { // ModelMetaInfo returns the meta information for the model. // // This is used to store information about the model, such as relational information, ModelMetaInfo() map[string]any }
CanMeta is an interface for defining a model that can have meta information.
This meta information is then stored on the ModelMeta interface.
type CanRelatedName ¶ added in v1.7.0
type DefaultGetter ¶
type Definer ¶
type Definer interface { // Retrieves the field definitions for the model. FieldDefs() Definitions }
Definer is the interface that wraps the FieldDefs method.
FieldDefs retrieves the field definitions for the model.
func DefinerList ¶ added in v1.6.7
DefinerList converts a slice of []T where the underlying type is of type Definer to []Definer.
type Definitions ¶
type Definitions interface { // Set sets the value of the field with the given name (or panics if not found). Set(name string, value interface{}) error // Retrieves the value of the field with the given name (or panics if not found). Get(name string) interface{} // contains filtered or unexported methods }
Definitions is the interface that wraps the methods for a model's field definitions.
This is some sort of management- interface which allows for simpler and more uniform management of model fields.
func AutoDefinitions ¶
func AutoDefinitions[T Definer](instance T, include ...any) Definitions
AutoDefinitions automatically generates definitions for a struct.
It does this by iterating over the fields of the struct and checking for the `attrs` tag. If the tag is present, it will parse the tag and generate the definition.
If the `include` parameter is provided, it will only generate definitions for the fields that are included.
type Field ¶
type Field interface { FieldDefinition // Scan the value of the field into your model. // // This allows for reading the value easily from the database. sql.Scanner // Return the value of the field as a driver.Value. // // This value should be used for storing the field in a database. // // If the field is nil or the zero value, the default value should be returned. driver.Valuer // ToString returns a string representation of the value. // // This should be the human-readable version of the value, for example for a list display. ToString() string // Retrieves the value of the field. GetValue() interface{} // Retrieves the default value of the field. // // Fields should also check the main model instance for methods like `GetDefault<FieldName>` to retrieve the default value. GetDefault() interface{} // Sets the value of the field. // // If the field is not allowed to be edited, this method should panic. // If the field is not allowed to be null, this method should panic when trying to set the value to nil / a reflect.Invalid value. // If the field is not allowed to be blank, this method should panic when trying to set the value to a blank value if the field is not of types: SetValue(v interface{}, force bool) error }
type FieldConfig ¶
type FieldConfig struct { Null bool // Whether the field allows null values Blank bool // Whether the field allows blank values ReadOnly bool // Whether the field is read-only Primary bool // Whether the field is a primary key NameOverride string // An optional override for the field name Label string // The label for the field HelpText string // The help text for the field Column string // The name of the column in the database MinLength int64 // The minimum length of the field MaxLength int64 // The maximum length of the field MinValue float64 // The minimum value of the field MaxValue float64 // The maximum value of the field Attributes map[string]interface{} // The attributes for the field RelForeignKey Relation // The related object for the field (foreign key) RelManyToMany Relation // The related objects for the field (many to many, not implemented RelOneToOne Relation // The related object for the field (one to one, not implemented) RelForeignKeyReverse Relation // The reverse foreign key for the field (not implemented) Default any // The default value for the field (or a function that takes in the object type and returns the default value) Validators []func(interface{}) error // Validators for the field FormField func(opts ...func(fields.Field)) fields.Field // The form field for the field WidgetAttrs map[string]string // The attributes for the widget FormWidget func(FieldConfig) widgets.Widget // The form widget for the field Setter func(Definer, interface{}) error // A custom setter for the field Getter func(Definer) (interface{}, bool) // A custom getter for the field OnInit func(Definer, *FieldDef, *FieldConfig) *FieldConfig // A function that is called when the field is initialized }
FieldConfig is a configuration for a field.
This defines how a field should behave and how it should be displayed in a form.
type FieldDef ¶
type FieldDef struct {
// contains filtered or unexported fields
}
func NewField ¶
func NewField(instance any, name string, conf *FieldConfig) *FieldDef
NewField creates a new field definition for the given instance.
This can then be used for managing the field in a more abstract way.
func (*FieldDef) AllowBlank ¶
func (*FieldDef) ColumnName ¶ added in v1.7.0
func (*FieldDef) GetDefault ¶
func (f *FieldDef) GetDefault() interface{}
type FieldDefinition ¶ added in v1.7.0
type FieldDefinition interface { Name() string Labeler Helper // Tag retrieves the tag value for the field with the given name. Tag(name string) string // Retrieves the underlying model instance. Instance() Definer // ColumnName retrieves the name of the column in the database. // // This can be used to generate the SQL for the field. ColumnName() string // Type returns the reflect.Type of the field. Type() reflect.Type // Attrs returns any extra attributes for the field, these can be used for multiple purposes. // // Additional info can be stored here, for example - if the field has a min / max length. Attrs() map[string]any // Rel etrieves the related model instance for a foreign key field. // // This could be used to generate the SQL for the field. Rel() Relation // Reports whether the field is the primary field. // // A model can technically have multiple primary fields, but this is not recommended. // // When for example, calling `Primary()` on the `Definitions` interface - only one will be returned. IsPrimary() bool // Reports whether the field is allowed to be null. // // If not, the field should panic when trying to set the value to nil / a reflect.Invalid value. AllowNull() bool // Reports whether the field is allowed to be blank. // // If not, the field should panic when trying to set the value to a blank value if the field is not of types: // bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128. // // this means that for example, a string field should panic when trying to set the value to an empty string. AllowBlank() bool // Reports whether the field is allowed to be edited. // // If not, the field should panic when trying to set the value, unless the force parameter passed to the `SetValue` method is true. AllowEdit() bool // Retrieves the form field for the field. // // This is used to generate forms for the field. FormField() fields.Field // Validates the field's value. Validate() error }
type FormFieldGetter ¶
type Helper ¶
type Helper interface { // HelpText returns a description of the field. // // This is displayed to the user in for example, forms. HelpText() string }
type Labeler ¶
type Labeler interface { // Label returns the human-readable name of the field. // // This is the name that is displayed to the user in for example, forms and column headers. Label() string }
type ModelMeta ¶ added in v1.7.0
type ModelMeta interface { // Model returns the model for this meta Model() Definer // Forward returns the forward relations for this model // which belong to the field with the given name. Forward(relField string) (Relation, bool) // Reverse returns the reverse relations for this model // which belong to the field with the given name. Reverse(relField string) (Relation, bool) // ForwardMap returns a copy the forward relations map for this model ForwardMap() *orderedmap.OrderedMap[string, Relation] // ReverseMap returns a copy of the reverse relations map for this model ReverseMap() *orderedmap.OrderedMap[string, Relation] // Storage returns a value stored on the model meta. // // This is used to store values that are not part of the model itself, // but are needed for the model or possible third party libraries to function. // // Values can be stored on the model meta using the `attrs.StoreOnMeta` helper function. // // A model can also implement the `CanModelInfo` interface to store values on the model meta. Storage(key string) (any, bool) // Definitions returns the field definitions for the model. // // This is used to retrieve meta information about fields, such as their type, // and other information that is not part of the model itself. Definitions() StaticDefinitions }
ModelMeta represents the meta information for a model.
This is used to store information about the model, such as relational information, and other information that is not part of the model itself.
Models which implement the `Definer` interface
func GetModelMeta ¶ added in v1.7.0
type ObjectDefinitions ¶
type ObjectDefinitions struct { Object Definer PrimaryField string Table string ObjectFields *orderedmap.OrderedMap[string, Field] }
func Define ¶
func Define(d Definer, fieldDefinitions ...Field) *ObjectDefinitions
Define creates a new object definitions.
This can then be returned by the FieldDefs method of a model to make it comply with the Definer interface.
func (*ObjectDefinitions) Fields ¶
func (d *ObjectDefinitions) Fields() []Field
func (*ObjectDefinitions) ForceSet ¶
func (d *ObjectDefinitions) ForceSet(name string, value interface{}) error
func (*ObjectDefinitions) Get ¶
func (d *ObjectDefinitions) Get(name string) interface{}
func (*ObjectDefinitions) Instance ¶ added in v1.6.9
func (d *ObjectDefinitions) Instance() Definer
func (*ObjectDefinitions) Len ¶
func (d *ObjectDefinitions) Len() int
func (*ObjectDefinitions) Primary ¶
func (d *ObjectDefinitions) Primary() Field
func (*ObjectDefinitions) Set ¶
func (d *ObjectDefinitions) Set(name string, value interface{}) error
func (*ObjectDefinitions) TableName ¶ added in v1.7.0
func (d *ObjectDefinitions) TableName() string
func (*ObjectDefinitions) WithTableName ¶ added in v1.7.0
func (d *ObjectDefinitions) WithTableName(name string) *ObjectDefinitions
type PathMetaChain ¶ added in v1.7.0
type PathMetaChain []*pathMeta
func WalkMetaFields ¶ added in v1.7.0
func WalkMetaFields(m Definer, path string) (PathMetaChain, error)
func (PathMetaChain) First ¶ added in v1.7.0
func (c PathMetaChain) First() *pathMeta
func (PathMetaChain) Last ¶ added in v1.7.0
func (c PathMetaChain) Last() *pathMeta
type Relation ¶ added in v1.7.0
type Relation interface { RelationTarget Type() RelationType // A through model for the relationship. // // This can be nil, but does not have to be. // It can support a one to one relationship with or without a through model, // or a many to many relationship with a through model. Through() Through }
Relation is an interface for defining a relation between two models.
This provides a very abstract way of defining relations between models, which can be used to define relations in a more generic way.
func GetRelationMeta ¶ added in v1.7.0
func Relate ¶ added in v1.7.0
Relate creates a new relation between two models.
This can be used to define all kinds of relations between models, such as one to one, one to many, many to many, many to one.
The target model is the model that is being related to. The target field is the field in the target model that is being related to, it can be an empty string, in which case the primary field of the target model is used.
The through model is the model that is used to link the two models together, it can be nil if not needed.
type RelationTarget ¶ added in v1.7.0
type RelationTarget interface { // From represents the source model for the relationship. // // If this is nil then the current interface value is the source model. From() RelationTarget // The target model for the relationship. Model() Definer // Field retrieves the field in the target model for the relationship. // // This can be nil, in such cases the relationship should use the primary field of the target model. // // If a through model is used, the target field should still target the actual target model, // the through model should then use this field to link to the target model. Field() FieldDefinition }
RelationTarget is an interface for defining a relation target.
This is the target model for the relation, which can be used to define the relation in a more generic way.
type RelationType ¶ added in v1.7.0
type RelationType int
const ( // ManyToOne is a many to one relationship, also known as a foreign key relationship. // // This means that the target model can have multiple instances of the source model, // but the source model can only have one instance of the target model. // This is the default type for a relation. RelManyToOne RelationType = iota // OneToOne is a one to one relationship. // // This means that the target model can only have one instance of the source model. // This is the default type for a relation. RelOneToOne // ManyToMany is a many to many relationship. // // This means that the target model can have multiple instances of the source model, // and the source model can have multiple instances of the target model. RelManyToMany // OneToMany is a one to many relationship, also known as a reverse foreign key relationship. // // This means that the target model can only have one instance of the source model, // but the source model can have multiple instances of the target model. RelOneToMany )
func (RelationType) MarshalJSON ¶ added in v1.7.0
func (r RelationType) MarshalJSON() ([]byte, error)
func (RelationType) String ¶ added in v1.7.0
func (r RelationType) String() string
func (*RelationType) UnmarshalJSON ¶ added in v1.7.0
func (r *RelationType) UnmarshalJSON(data []byte) error
type StaticDefinitions ¶ added in v1.7.0
type StaticDefinitions = staticDefinitions[FieldDefinition]
type Through ¶ added in v1.7.0
type Through interface { // The through model itself. Model() Definer // The source field for the relation - this is a field in the through model linking to the source model. SourceField() string // The target field for the relation - this is a field in the through model linking to the target model. TargetField() string }
Through is an interface for defining a relation between two models.
This provides a very abstract way of defining relations between models, which can be used to define one to one relations or many to many relations.
type ThroughModel ¶ added in v1.7.0
func (*ThroughModel) Model ¶ added in v1.7.0
func (t *ThroughModel) Model() Definer
Model returns the through model itself.
func (*ThroughModel) SourceField ¶ added in v1.7.0
func (t *ThroughModel) SourceField() string
SourceField returns the source field for the relation - this is the field in the source model.
func (*ThroughModel) TargetField ¶ added in v1.7.0
func (t *ThroughModel) TargetField() string
TargetField returns the target field for the relation - this is the field in the target model, or in the next through model.