attrs

package
v1.7.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: GPL-2.0 Imports: 35 Imported by: 23

Documentation

Index

Constants

View Source
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.

View Source
const (
	HookFormFieldForType = "attrs.FormFieldForType"
	DefaultForType       = "attrs.DefaultForType"
)
View Source
const ATTR_TAG_NAME = "attrs"
View Source
const (
	MetaStorageKeyAttrs = "fields.attributes"
)

Variables

View Source
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
	})
}
View Source
var (
	ALLOW_METHOD_CHECKS = false // Whether to allow method checks for getters and setters

)

Functions

func BindValueToModel added in v1.7.2

func BindValueToModel(model Definer, field Field, value any) error

BindValueToModel binds the given model and field to the value.

func ColumnName added in v1.7.2

func ColumnName(str string) string

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

func FieldNames(d any, exclude []string) []string

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

func ForceSet(d Definer, name string, value interface{}) error

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

func Get[T any](d any, name string) T

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 GetFromAttributes[T any](attrMap map[string]any, key string) (T, bool)

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 IsModelRegistered(model Definer) bool

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

func Method[T Function](obj interface{}, name string) (n T, ok bool)

Method retrieves a method from an object.

The generic type parameter must be the type of the method.

func ModelMixins added in v1.7.2

func ModelMixins(obj Definer, topdown bool) iter.Seq2[any, int]

func NewObject added in v1.7.2

func NewObject[T Definer](definer any) T

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 NiceName added in v1.7.2

func NiceName(str string) string

NiceName returns a human-readable name for the given field name.

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 RegisterFormFieldType(valueOfType any, getField func(opts ...func(fields.Field)) fields.Field)

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 RegisterNewObjectFunc(typ reflect.Type, fn func(original any) Definer)

func Set

func Set(d Definer, name string, value interface{}) error

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

func SetMany(d Definer, values map[string]interface{}) error

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

func SetPrimaryKey(d Definer, value interface{}) error

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 StoreOnMeta(m Definer, key string, value any)

func ToBool added in v1.7.2

func ToBool(v any) (bool, error)

func ToFloat added in v1.7.2

func ToFloat(v any) (float64, error)

func ToInt added in v1.7.2

func ToInt(v any) (int64, error)

func ToString

func ToString(v any) string

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 ToTime added in v1.7.2

func ToTime(v any) (time.Time, error)

func UnpackFieldsFromArgsIter added in v1.7.2

func UnpackFieldsFromArgsIter[T1 Definer, T2 any](definer T1, args ...T2) iter.Seq2[Field, error]

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

type CanOnModelRegister interface {
	Field
	OnModelRegister(model Definer) error
}

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

type CanRelatedName interface {
	Field
	RelatedName() string
}

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 DefaultGetter func(f Field, new_field_t_indirected reflect.Type, field_v reflect.Value) (interface{}, bool)

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

func DefinerList[T Definer](list []T) []Definer

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

type Embedded interface {
	BindToEmbedder(embedder Definer) error
}

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

func AutoFieldList[T1 Definer](instance T1, include ...any) []Field

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

func UnpackFieldsFromArgs[T1 Definer, T2 any](definer T1, args ...T2) ([]Field, error)

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 (f *FieldDef) AllowBlank() bool

func (*FieldDef) AllowEdit

func (f *FieldDef) AllowEdit() bool

func (*FieldDef) AllowNull

func (f *FieldDef) AllowNull() bool

func (*FieldDef) Attrs added in v1.7.0

func (f *FieldDef) Attrs() map[string]interface{}

func (*FieldDef) BindToDefinitions added in v1.7.2

func (f *FieldDef) BindToDefinitions(defs Definitions)

func (*FieldDef) Check added in v1.7.2

func (f *FieldDef) Check(ctx context.Context) []checks.Message

Check checks if the field is valid and can be used.

func (*FieldDef) ColumnName added in v1.7.0

func (f *FieldDef) ColumnName() string

func (*FieldDef) Embedded added in v1.7.2

func (f *FieldDef) Embedded() bool

func (*FieldDef) FieldDefinitions added in v1.7.2

func (f *FieldDef) FieldDefinitions() Definitions

func (*FieldDef) FormField

func (f *FieldDef) FormField() fields.Field

func (*FieldDef) GetDefault

func (f *FieldDef) GetDefault() interface{}

func (*FieldDef) GetValue

func (f *FieldDef) GetValue() interface{}

func (*FieldDef) HelpText

func (f *FieldDef) HelpText(ctx context.Context) string

func (*FieldDef) Instance

func (f *FieldDef) Instance() Definer

func (*FieldDef) IsPrimary

func (f *FieldDef) IsPrimary() bool

func (*FieldDef) Label

func (f *FieldDef) Label(ctx context.Context) string

func (*FieldDef) Name

func (f *FieldDef) Name() string

func (*FieldDef) OnModelRegister added in v1.7.2

func (f *FieldDef) OnModelRegister(model Definer) error

model is equal to instance_t

func (*FieldDef) Rel added in v1.6.7

func (f *FieldDef) Rel() Relation

func (*FieldDef) Scan added in v1.7.0

func (f *FieldDef) Scan(value any) error

func (*FieldDef) SetValue

func (f *FieldDef) SetValue(v interface{}, force bool) error

func (*FieldDef) Tag added in v1.7.0

func (f *FieldDef) Tag(name string) string

func (*FieldDef) ToString

func (f *FieldDef) ToString() string

func (*FieldDef) Type added in v1.7.0

func (f *FieldDef) Type() reflect.Type

func (*FieldDef) TypeString added in v1.7.2

func (f *FieldDef) TypeString() string

func (*FieldDef) Validate

func (f *FieldDef) Validate() error

func (*FieldDef) Value added in v1.7.0

func (f *FieldDef) Value() (driver.Value, error)

Returns 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 is returned.

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

type FieldUnpackerMixin interface {
	ObjectFields(object Definer, base_fields *FieldsMap) error
}

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
}

func (*FieldsMap) Get added in v1.7.2

func (d *FieldsMap) Get(name string) (f Field, ok bool)

func (*FieldsMap) Iter added in v1.7.2

func (d *FieldsMap) Iter() iter.Seq2[string, Field]

func (*FieldsMap) Len added in v1.7.2

func (d *FieldsMap) Len() int

func (*FieldsMap) Set added in v1.7.2

func (d *FieldsMap) Set(name string, f Field) (replaced bool)

type FormFieldGetter

type FormFieldGetter func(f Field, new_field_t_indirected reflect.Type, field_v reflect.Value, opts ...func(fields.Field)) (fields.Field, bool)

type Function added in v1.7.2

type Function interface{}

type Helper

type Helper interface {
	// HelpText returns a description of the field.
	//
	// This is displayed to the user in for example, forms.
	HelpText(ctx context.Context) 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(ctx context.Context) string
}

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 LazyThrough interface {
	Through

	// ModelKey returns the key of the model in the lazy registry.
	ModelKey() 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]

	// 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

func GetModelMeta(model any) ModelMeta

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) Field

func (d *ObjectDefinitions) Field(name string) (f Field, ok bool)

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 GetRelationMeta(m Definer, name string) (Relation, bool)

func Relate added in v1.7.0

func Relate(target Definer, targetField string, through Through) Relation

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.

func ReverseRelation added in v1.7.0

func ReverseRelation(
	fromModel Definer,
	fromField Field,
	forward Relation,
) Relation

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 Scanner

type Scanner interface {
	// ScanAttribute scans the value of the attribute.
	//
	// This is used to set the value of the field from a raw value.
	ScanAttribute(src any) 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 SignalThroughModelMeta struct {
	Source      Definer
	Target      Definer
	ThroughInfo Through
	Meta        ModelMeta
}

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.

func ThroughDeferred added in v1.7.2

func ThroughDeferred(
	modelKey string,
	sourceField string,
	targetField string,
) Through

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

type ThroughModel struct {
	This   Definer
	Source string
	Target string
}

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 ToTimeConverter interface {
	ToTime() time.Time
}

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

type WalkFieldsFunc added in v1.7.2

type WalkFieldsFunc func(source Relation, meta ModelMeta, object Definer, field FieldDefinition, fieldRel Relation, part string, parts []string, idx int) (stop bool, err error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL