Skip to main content

Field Reference

Ryx fields are descriptors. A field stores model metadata, validates Python values, converts values to database values, and exposes SQL type information to the migration system.

Common Field Optionsโ€‹

All field classes inherit these options from Field:

OptionDefaultPurpose
nullFalseAllows SQL NULL
blankFalseAllows empty values during validation
defaultnoneStatic value or callable default
primary_keyFalseMarks the model primary key
uniqueFalseAdds uniqueness validation/constraint metadata
db_indexFalseMarks the field for index creation
choicesNoneRestricts values with ChoicesValidator
validators[]Extra validator instances
editableTrueExcluded from save() when False, except auto timestamp fields
help_text""Human-readable description
verbose_name""Human-readable label
db_columnfield nameOverrides the SQL column name
unique_for_dateNoneDeclares date-scoped uniqueness metadata
unique_for_monthNoneDeclares month-scoped uniqueness metadata
unique_for_yearNoneDeclares year-scoped uniqueness metadata
title = CharField(
max_length=200,
null=False,
blank=False,
default="Untitled",
unique=True,
db_index=True,
choices=["draft", "published"],
db_column="post_title",
)

If no primary key is declared on a concrete model, Ryx injects:

id = AutoField(primary_key=True, editable=False)

Integer Fieldsโ€‹

FieldSQL TypePython TypeExtra Options
AutoFieldSERIALintUsually primary key
BigAutoFieldBIGSERIALintLarge auto primary key
SmallAutoFieldSMALLSERIALintSmall auto primary key
IntFieldINTEGERintmin_value, max_value
SmallIntFieldSMALLINTintmin_value, max_value
BigIntFieldBIGINTintmin_value, max_value
PositiveIntFieldINTEGERintAdds min_value=0 behavior
class Product(Model):
stock = PositiveIntField(default=0)
rating = SmallIntField(min_value=1, max_value=5)

Numeric Fieldsโ€‹

FieldSQL TypePython TypeExtra Options
FloatFieldDOUBLE PRECISIONfloatmin_value, max_value
DecimalFieldNUMERIC(max_digits, decimal_places)Decimalmax_digits, decimal_places
price = DecimalField(max_digits=10, decimal_places=2)
score = FloatField(min_value=0.0, max_value=1.0)

Boolean Fieldsโ€‹

FieldSQL TypePython TypeNotes
BooleanFieldBOOLEANboolStandard boolean
NullBooleanFieldBOOLEAN`boolNone`

Text Fieldsโ€‹

FieldSQL TypePython TypeExtra Options
CharFieldVARCHAR(max_length)strmax_length, min_length, strip
TextFieldTEXTstrmin_length
SlugFieldVARCHAR(50)strSlug-style validation
EmailFieldVARCHAR(254)strEmail validation
URLFieldVARCHAR(200)strURL validation
IPAddressFieldVARCHAR(15)strIPv4 validation
slug = SlugField(unique=True)
email = EmailField(unique=True)
bio = TextField(blank=True)

Date and Time Fieldsโ€‹

FieldSQL TypePython TypeExtra Options
DateFieldDATEdateauto_now, auto_now_add
DateTimeFieldTIMESTAMPdatetimeauto_now, auto_now_add
TimeFieldTIMEtimeโ€”
DurationFieldBIGINTtimedeltaStored as microseconds
created_at = DateTimeField(auto_now_add=True)
updated_at = DateTimeField(auto_now=True)
publish_date = DateField(null=True)

auto_now_add updates only on insert. auto_now updates on every save.

Structured and Binary Fieldsโ€‹

FieldSQL TypePython TypeExtra Options
UUIDFieldUUIDuuid.UUIDauto_create
JSONFieldJSONB`dictlist`
ArrayField<base>[]listbase_field
BinaryFieldBYTEAbytesโ€”
uid = UUIDField(auto_create=True, unique=True)
metadata = JSONField(default=dict)
tags = ArrayField(CharField(max_length=40), default=list)
payload = BinaryField(null=True)

JSON lookups include has_key, has_any, has_all, contains, and contained_by. JSON transforms include key, key_text, and json.

Relationship Fieldsโ€‹

FieldDatabase RepresentationPython UseExtra Options
ForeignKeyFK id columnForward descriptor + reverse managerto, on_delete, related_name
OneToOneFieldUnique FK id columnOne-to-one descriptorSame as ForeignKey
ManyToManyFieldThrough tableMany-to-many managerto, through, related_name
class Author(Model):
name = CharField(max_length=100)

class Post(Model):
author = ForeignKey(Author, on_delete="CASCADE", related_name="posts")

class Profile(Model):
author = OneToOneField(Author, on_delete="CASCADE")

Supported on_delete values are interpreted by the field and migration layer. Use the exact values demonstrated in examples and tests, such as "CASCADE".

Validationโ€‹

Field validation combines:

  1. NotNullValidator for non-null, non-primary-key fields
  2. ChoicesValidator when choices is provided
  3. UniqueValueValidator when unique=True
  4. Field-specific validators such as length, range, email, URL, or regex
  5. Explicit validators passed in validators=[...]
from ryx import CharField, RegexValidator

username = CharField(
max_length=40,
validators=[RegexValidator(r"^[a-z0-9_]+$")],
)

Lookup Validationโ€‹

Each field class declares supported lookups and transforms. Ryx validates lookup chains before sending a query to Rust:

await Post.objects.filter(title__icontains="ryx")
await Post.objects.filter(created_at__year__gte=2025)
await Post.objects.filter(metadata__key_text__icontains="error")

Unknown lookup suffixes fall back to exact matching during parsing, so prefer ryx.available_lookups() and this reference when authoring advanced filters.

Migration Metadataโ€‹

Fields expose db_type() and deconstruct() data used by:

  • project_state_from_models()
  • Autodetector
  • DDLGenerator
  • MigrationRunner

For unmanaged legacy tables, set:

class LegacyUser(Model):
name = CharField(max_length=100)

class Meta:
table_name = "legacy_users"
managed = False

managed=False keeps the model queryable while preventing migration generation from creating or altering its table.