Documentation
¶
Index ¶
- Constants
- Variables
- func BindValueToModel(model Definer, field Field, value any) error
- func ColumnName(str string) string
- func FieldAttribute[T any](ctx context.Context, model Definer, fieldName string, attrName string) (context.Context, T, bool)
- func FieldNames(d any, exclude []string) []string
- func ForceSet(d Definer, name string, value interface{}) error
- func Get[T any](d any, name string) T
- func GetFromAttributes[T any](attrMap map[string]any, key string) (T, bool)
- func IsEmbeddedField[T FieldDefinition](f T) bool
- func IsModelRegistered(model Definer) bool
- func IsZero(value interface{}) bool
- func Method[T Function](obj interface{}, name string) (n T, ok bool)
- func ModelMixins(obj Definer, topdown bool) iter.Seq2[any, int]
- func NewObject[T Definer](definer any) T
- func NiceName(str string) string
- func PrimaryKey(d Definer) interface{}
- func RegisterDefaultType(valueOfType any, ...)
- func RegisterFormFieldGetter(valueOfType any, getField FormFieldGetter)
- func RegisterFormFieldType(valueOfType any, getField func(opts ...func(fields.Field)) fields.Field)
- func RegisterModel(model Definer)
- func RegisterNewObjectFunc(typ reflect.Type, fn func(original any) 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 ToBool(v any) (bool, error)
- func ToFloat(v any) (float64, error)
- func ToInt(v any) (int64, error)
- func ToString(v any) string
- func ToTime(v any) (time.Time, error)
- func UnpackFieldsFromArgsIter[T1 Definer, T2 any](definer T1, args ...T2) iter.Seq2[Field, error]
- func WalkMetaFieldsFunc(m Definer, path []string, fn WalkFieldsFunc) error
- type Binder
- type CanCreateObject
- type CanModelInfo
- type CanOnModelRegister
- type CanRelatedName
- type CanReverseRelate
- type CanSetup
- type CanSignalChanged
- type DefaultGetter
- type Definer
- type Definitions
- type Embedded
- type Embedder
- 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) BindToDefinitions(defs Definitions)
- func (f *FieldDef) Check(ctx context.Context) []checks.Message
- func (f *FieldDef) ColumnName() string
- func (f *FieldDef) Embedded() bool
- func (f *FieldDef) FieldDefinitions() Definitions
- func (f *FieldDef) FormField() fields.Field
- func (f *FieldDef) GetDefault() interface{}
- func (f *FieldDef) GetValue() interface{}
- func (f *FieldDef) HelpText(ctx context.Context) string
- func (f *FieldDef) Instance() Definer
- func (f *FieldDef) IsPrimary() bool
- func (f *FieldDef) Label(ctx context.Context) string
- func (f *FieldDef) Name() string
- func (f *FieldDef) OnModelRegister(model Definer) error
- 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) TypeString() string
- func (f *FieldDef) Validate() error
- func (f *FieldDef) Value() (driver.Value, error)
- type FieldDefinition
- type FieldUnpackerMixin
- type FieldsMap
- type FormFieldGetter
- type Function
- type Helper
- type Labeler
- type LazyRelation
- type LazyThrough
- 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) SignalChange(f Field, value interface{})
- func (d *ObjectDefinitions) SignalReset(f Field)
- func (d *ObjectDefinitions) TableName() string
- func (d *ObjectDefinitions) WithTableName(name string) *ObjectDefinitions
- type PathMetaChain
- type Relation
- type RelationChain
- type RelationChainPart
- type RelationTarget
- type RelationType
- type Scanner
- type SignalModelMeta
- type SignalThroughModelMeta
- type StaticDefinitions
- type Through
- type ThroughMeta
- type ThroughModel
- type ToBoolConverter
- type ToFloatConverter
- type ToIntConverter
- type ToStringConverter
- type ToTimeConverter
- type UnboundField
- type UnboundFieldConstructor
- type WalkFieldsFunc
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" // AttrPrecisionKey (int64) is the precision of a field which supports it, such as a decimal field. AttrPrecisionKey = "field.precision" // AttrScaleKey (int64) is the scale of a field which supports it, such as a decimal field. AttrScaleKey = "field.scale" // AttrUploadToKey (string) is the upload path base for a file field. AttrUploadToKey = "field.upload_to" )
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"
const (
MetaStorageKeyAttrs = "fields.attributes"
)
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") // A signal that is called when a through model is registered. // // This is only sent from the forward relation side, // not when the through model is actually registered. OnThroughModelRegister = throughSignalPool.Get("attrs.OnThroughModelRegister") // ResetDefinitions is a signal that can be sent to reset the static definitions of all models. // // This should be done after all models have been registered, so that the static definitions have enough information to be built correctly. ResetDefinitions = signals.New[any]("attrs.ResetDefinitions") )
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 (
ALLOW_METHOD_CHECKS = false // Whether to allow method checks for getters and setters
)
Functions ¶
func BindValueToModel ¶ added in v1.7.2
BindValueToModel binds the given model and field to the value.
func ColumnName ¶ added in v1.7.2
ColumnName returns a column name for the given field name. To get an actual column name for a field, you should use the `ColumnName` method on the `attrs.FieldDefinition`.
func FieldAttribute ¶ added in v1.7.2
func FieldAttribute[T any](ctx context.Context, model Definer, fieldName string, attrName string) (context.Context, T, bool)
FieldAttribute retrieves an attribute of a field in a model.
It returns the context with the field attribute map, the attribute value, and a boolean indicating if the attribute was found.
The context can be used for subsequent calls to retrieve attributes without needing to re-fetch them from the model meta.
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 GetFromAttributes ¶ added in v1.7.2
func IsEmbeddedField ¶ added in v1.7.2
func IsEmbeddedField[T FieldDefinition](f T) bool
IsEmbeddedField returns true if the field was marked as embedded.
This is used to determine if the field is an embedded field in a model, I.E. it belongs to an embedded or proxy model.
func IsModelRegistered ¶ added in v1.7.0
func IsZero ¶ added in v1.7.2
func IsZero(value interface{}) bool
IsZero checks if a value is set to its zero value. It works on any value, including pointers, slices, maps, and structs.
- For slices it checks if the slice is empty and all elements are zero values.
- For maps it checks if the map is empty.
- For pointers it checks if the pointer is nil or if the value it points to is a zero value.
func Method ¶
Method retrieves a method from an object.
The generic type parameter must be the type of the method.
func NewObject ¶ added in v1.7.2
Creates a new object from the given Definer type.
This function should always be used to create new objects from a Definer type, as it will ensure that the object is properly set up and initialized.
This function takes the following types of input: - A reflect.Type of the Definer to create an object from. - A string which is assumed to be the content type of T - A contenttypes.ContentType from which a T can be derived. - Any other value which can be safely cast to T
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 RegisterFormFieldGetter ¶ added in v1.7.2
func RegisterFormFieldGetter(valueOfType any, getField FormFieldGetter)
func RegisterFormFieldType ¶
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 RegisterNewObjectFunc ¶ added in v1.7.2
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.
func UnpackFieldsFromArgsIter ¶ added in v1.7.2
UnpackFieldsFromArgsIter unpacks the fields from the given arguments.
It returns an iterator that yields fields and errors.
The fields are passed as variadic arguments, and can be of many types:
- Field: a field (or any type that implements the Field interface) - []Field: a slice of fields - UnboundFieldConstruuctor: a constructor for a field that needs to be bound - []UnboundFieldConstructor: a slice of unbound field constructors - UnboundField: an unbound field that needs to be bound - []UnboundField: a slice of unbound fields that need to be bound - iter.Seq2[Field, error]: iterators to possibly increase performance - func() iter.Seq2[Field, error]: iterators to possibly increase performance - func(Definer) iter.Seq2[Field, error]: iterators to possibly increase performance - func() []any: a function of which the result will be recursively unpacked - func() Field: a function that returns a field - func() (Field, error): a function that returns a field and an error - func() []Field: a function that returns a slice of fields - func() ([]Field, error): a function that returns a slice of fields and an error - func(d Definer) []any: a function that takes a Definer and returns a slice of any to be recursively unpacked - func(d Definer) Field: a function that takes a Definer and returns a field - func(d Definer) (Field, error): a function that takes a Definer and returns a field and an error - func(d Definer) []Field: a function that takes a Definer and returns a slice of fields - func(d Definer) ([]Field, error): a function that takes a Definer and returns a slice of fields and an error - func(d T1) []any: a function that takes a Definer of type T1 and returns a slice of any to be recursively unpacked - func(d T1) Field: a function that takes a Definer of type T1 and returns a field - func(d T1) (Field, error): a function that takes a Definer of type T1 and returns a field and an error - func(d T1) []Field: a function that takes a Definer of type T1 and returns a slice of fields - func(d T1) ([]Field, error): a function that takes a Definer of type T1 and returns a slice of fields and an error - string: a field name, which will be converted to a Field with no configuration
func WalkMetaFieldsFunc ¶ added in v1.7.2
func WalkMetaFieldsFunc(m Definer, path []string, fn WalkFieldsFunc) error
Types ¶
type Binder ¶ added in v1.7.2
type Binder interface {
// Bind binds the value to the model.
BindToModel(model Definer, field Field) error
}
A binder is a value which can be bound to a model.
Any fields should call the `Bind` method to bind the value to the model, this has to be done when: - the field value is set (SetValue method is called) - the field value is retrieved (GetValue method is called) - the default value is retrieved (GetDefault method is called) - the field value is scanned (Scan method is called) - the driver.Value is retrieved (Value method is called)
type CanCreateObject ¶ added in v1.7.2
type CanCreateObject[T Definer] interface { // CreateObject creates a new object being the same // type as the source model provided in the method. // // This might be useful for creating new objects // when the embedder needs information from the source model, // such as the content type or other attributes. CreateObject(source T) T }
CanCreateObject is an interface for models that can create new objects of the same type.
If the type is not the same as the model (for example when embedding a model), the newly created object will not be used.
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(object Definer) 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 CanOnModelRegister ¶ added in v1.7.2
CanOnModelRegister defines a method that is called when the model is registered.
This method is called once, and only once.
See OnModelRegister and RegisterModel for the implementation details.
type CanRelatedName ¶ added in v1.7.0
CanRelatedName is an interface for fields that have a related name.
This is used to define the name of the field in the related model.
type CanReverseRelate ¶ added in v1.7.2
type CanReverseRelate interface {
Field
// ReverseRelate returns false, indicating that the field cannot be reverse related.
AllowReverseRelation() bool
}
CanReverseRelate is an interface for fields to indicate that no reverse relation should be created.
type CanSetup ¶ added in v1.7.2
type CanSetup interface {
Setup()
}
A model can implement the CanSetup interface to perform any setup that is needed for the model.
This is called when the model is created with the NewObject function.
type CanSignalChanged ¶ added in v1.7.2
type CanSignalChanged interface {
// Changed is a function that is called when a field is changed.
//
// This is used to notify the model that a field has changed,
// so that the model can update its state accordingly.
SignalChange(f Field, value interface{})
// SignalReset is a function that should be called when a field saved, and thus the
// changed status should be reset.
SignalReset(f Field)
}
CanSignalChanged is an interface for models so that fields can signal their changes to the model.
This is used to notify the model that a field has changed, so that the model can update its state accordingly.
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 {
CanSignalChanged
// 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 Embedded ¶ added in v1.7.2
A field in a struct can implement the Embedded interface to bind itself to the Definer which should be the top-most model.
It allows for multiple values in a chain of embedded models to be bound to the top-most model.
This is only called when NewField is called.
type Embedder ¶ added in v1.7.2
type Embedder interface {
// Embedded should return true if the field belongs to a model
// that is embedded in another model.
Embedded() bool
}
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
// FieldDefs retrieves the field definitions for the model.
//
// Each time a field is changed, the field definitions should receive a signal that
// the field has changed.
FieldDefinitions() Definitions
// BindToDefinitions binds the field to the definitions of the model.
//
// This is used to bind the field to the model's definitions
// so that the field can send the appropriate signals when the field is changed.
BindToDefinitions(definitions Definitions)
// 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.
GetDefault() interface{}
// Sets the value of the field.
//
// If the field is not allowed to be edited and the force parameter is false, 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 a primitive type.
SetValue(v interface{}, force bool) error
// Validates the field's value.
Validate() error
}
func AutoFieldList ¶ added in v1.7.2
AutoFieldList automatically generates a list of fields 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.
func UnpackFieldsFromArgs ¶ added in v1.7.2
UnpackFieldsFromArgs unpacks the fields from the given arguments.
The fields are passed as variadic arguments, and can be of many types:
- Field: a field (or any type that implements the Field interface) - []Field: a slice of fields - UnboundFieldConstruuctor: a constructor for a field that needs to be bound - []UnboundFieldConstructor: a slice of unbound field constructors - UnboundField: an unbound field that needs to be bound - []UnboundField: a slice of unbound fields that need to be bound - func() []any: a function of which the result will be recursively unpacked - func() Field: a function that returns a field - func() (Field, error): a function that returns a field and an error - func() []Field: a function that returns a slice of fields - func() ([]Field, error): a function that returns a slice of fields and an error - func(d Definer) []any: a function that takes a Definer and returns a slice of any to be recursively unpacked - func(d Definer) Field: a function that takes a Definer and returns a field - func(d Definer) (Field, error): a function that takes a Definer and returns a field and an error - func(d Definer) []Field: a function that takes a Definer and returns a slice of fields - func(d Definer) ([]Field, error): a function that takes a Definer and returns a slice of fields and an error - func(d T1) []any: a function that takes a Definer of type T1 and returns a slice of any to be recursively unpacked - func(d T1) Field: a function that takes a Definer of type T1 and returns a field - func(d T1) (Field, error): a function that takes a Definer of type T1 and returns a field and an error - func(d T1) []Field: a function that takes a Definer of type T1 and returns a slice of fields - func(d T1) ([]Field, error): a function that takes a Definer of type T1 and returns a slice of fields and an error - string: a field name, which will be converted to a Field with no configuration
type FieldConfig ¶
type FieldConfig struct {
AutoInit bool // Whether the parent struct should be initialized automatically if the field is an embedded field
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
Embedded bool // Whether the field is an embedded field
NameOverride string // An optional override for the field name
Label any // The label for the field
HelpText any // 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) BindToDefinitions ¶ added in v1.7.2
func (f *FieldDef) BindToDefinitions(defs Definitions)
func (*FieldDef) ColumnName ¶ added in v1.7.0
func (*FieldDef) FieldDefinitions ¶ added in v1.7.2
func (f *FieldDef) FieldDefinitions() Definitions
func (*FieldDef) GetDefault ¶
func (f *FieldDef) GetDefault() interface{}
func (*FieldDef) OnModelRegister ¶ added in v1.7.2
model is equal to instance_t
func (*FieldDef) TypeString ¶ added in v1.7.2
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.
//
// For a field definition, this is likely not an actual instance of the model,
// for the Field interface, this is the actual 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
}
type FieldUnpackerMixin ¶ added in v1.7.2
FieldUnpackerMixin is an interface for model mixins that can add fields to a model. These mixins must be embedded in the model struct to retain the information. This is used by the Define function to unpack fields from the mixin. To define a model as having mixins, a `Mixin` method must be defined on the model, Mixins can have their own mixins, which will be unpacked recursively. An object with mixins *MUST* always implement the mixins.MixinDefiner interface.
type FieldsMap ¶ added in v1.7.2
type FieldsMap struct {
// contains filtered or unexported fields
}
type FormFieldGetter ¶
type LazyRelation ¶ added in v1.7.2
type LazyRelation interface {
Relation
// ModelKey returns the key of the model in the lazy registry.
ModelKey() string
}
func RelatedDeferred ¶ added in v1.7.2
func RelatedDeferred( typ RelationType, modelKey string, targetField string, through Through, ) LazyRelation
type LazyThrough ¶ added in v1.7.2
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]
// ContentType returns the content type for the model.
ContentType() contenttypes.ContentType
// 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 *FieldsMap
// contains filtered or unexported fields
}
func Define ¶
func Define[T1 Definer, T2 any](d T1, fieldDefinitions ...T2) *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.
For information about the arguments, see the UnpackFieldsFromArgs function.
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) SignalChange ¶ added in v1.7.2
func (d *ObjectDefinitions) SignalChange(f Field, value interface{})
func (*ObjectDefinitions) SignalReset ¶ added in v1.7.2
func (d *ObjectDefinitions) SignalReset(f Field)
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 RelationChain ¶ added in v1.7.2
type RelationChain struct {
Root *RelationChainPart
Final *RelationChainPart
Fields []FieldDefinition
Chain []string
}
func WalkRelationChain ¶ added in v1.7.2
func WalkRelationChain(m Definer, includeFinalRel bool, path []string) (*RelationChain, error)
type RelationChainPart ¶ added in v1.7.2
type RelationChainPart struct {
Next *RelationChainPart // the next part in the chain
Prev *RelationChainPart // the previous part in the chain
ChainPart string // the name of the field in the chain
FieldRel Relation // the relation of the field in the current part
Model Definer // the current target model
Through Through // the through relation to get to the target model, if any
Field FieldDefinition // the field in the current model, possibly containing the next relation
Depth int // corresponds to the index in chain.Chain
// contains filtered or unexported fields
}
func (*RelationChainPart) Chain ¶ added in v1.7.2
func (p *RelationChainPart) Chain() []string
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 ( // RelNone is a placeholder for no relation. // // This is used to distinguish from the zero value of a relation. // It is not a valid relation type. RelNone RelationType = iota // 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 // 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 SignalModelMeta ¶ added in v1.7.2
type SignalModelMeta struct {
Definer Definer
Definitions StaticDefinitions
Meta ModelMeta
}
type SignalThroughModelMeta ¶ added in v1.7.2
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 ThroughMeta ¶ added in v1.7.2
type ThroughMeta struct {
IsThroughModel bool
Source Definer
Target Definer
SourceField string
TargetField string
}
func ThroughModelMeta ¶ added in v1.7.2
func ThroughModelMeta(m Definer) ThroughMeta
func (ThroughMeta) GetSourceField ¶ added in v1.7.2
func (t ThroughMeta) GetSourceField(targetModel Definer, throughDefs Definitions) Field
func (ThroughMeta) GetTargetField ¶ added in v1.7.2
func (t ThroughMeta) GetTargetField(targetModel Definer, throughDefs Definitions) Field
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.
type ToBoolConverter ¶ added in v1.7.2
type ToBoolConverter interface {
ToBool() bool
}
type ToFloatConverter ¶ added in v1.7.2
type ToFloatConverter interface {
ToFloat() float64
}
type ToIntConverter ¶ added in v1.7.2
type ToIntConverter interface {
ToInt() int64
}
type ToStringConverter ¶ added in v1.7.2
type ToStringConverter interface {
ToString() string
}
type ToTimeConverter ¶ added in v1.7.2
type UnboundField ¶ added in v1.7.2
type UnboundField interface {
Field
UnboundFieldConstructor
}
An UnboundField is a field that is not bound to a model yet.
This is only used in the Define function to create a field definition. It is used to create a field that does not have to directly take a model as an argument, but can be bound to a model later.
type UnboundFieldConstructor ¶ added in v1.7.2
type UnboundFieldConstructor interface {
// Name returns the name of the field.
Name() string
// BindField binds the field to the model.
BindField(model Definer) (Field, error)
}
An unbound field constructor is an object that can bind a field to a model.
This is only called in Define.
It returns a field in case of a wrapper implementation, or an error in case the field cannot be bound to the model.
func Unbound ¶ added in v1.7.2
func Unbound(name string, cnf ...*FieldConfig) UnboundFieldConstructor