Questions?

Subscribe to out mailing list Google group:

Fields

Mask and Tables display a collection of data that may belong to the database or not. Each of the data represented in the GUI that needs to partecipate to any updating/saving process should have it’s own handler that is a Field.

A Field is an entity that knows how to handle a piece of data, be it on the database (a field_name) or just in the GUI. It’s a layer that allows gui widget to be simpler and easier to interchange. As an example, both varchars and integers are normally displayed by a gtk.Entry: the entry.get_text() will retrieve in both cases a string, it’s the Field (IntegerField) that knows how to turn that string into an integer using the Field.clean_value() method. In more complex cases clean_value can return data computed from related records.

cthe field knows:

  • if it belongs to the database (attribute persistent is True) and in case how it is defined ( i.e.: sqlalchemy property/column)
  • if it is nullable/editable
  • which widget must be used to represent it (see below, not requested)
  • how to produce a formatted representation of the field.

It provides functions to

  • set/get value
  • get default value (but will not cope with server_side defaults)
  • tell if it changed from the default
  • clean value according to it’s logic: i.e. return a value of the correct type
  • validate values (possibly according to other criteria)

The association between a database field and a Field is dome by FieldChooser, but you can force a particular Field when defining the model class setting the key field of the column’s info dictionary:

class MyClass(Base):
    ...
    foo = Column(..., info={'field' : MyField})

A last method is to use on_pre_layout hook that allows to set sqlkit.Fields even on non persisted fields.

Relation with the master sqlwidget

Currently there are a number of operation that require that the field know wich is the sqlwidget it is acting for. I’d like to loosen this connection in future but at present it’s used in the following situations:

  • to keep updated the list of field_widgets
  • to get default values (that can be local to a sqlwidget)
  • for validation purposes: to issue master.run_hooks and NonNullableException
  • FKey: to handle addition of related_obj when cascading policy requires it

In the meanwhile I add master to the Field via set_master() and add a widget to the Field via set_widget()

Db attributes

The costructor can be passed a dict of field_attributes

  • field_name: the name of the field

  • nullable: True if field is nullable or False. The related widget will get a background color that

    reflects the fact that it is required (currently yellow). This can be set at any time.

  • editable: True if field is editable or False. The related widget will be set unsensitive. This can

    be set at any time.

  • length: the desired length in chars

  • default: a possible default option

  • type: the python type

  • mapper: defined as None for field that are mapped

  • table: the SA Table object

  • column: the SA Column object

  • property: the SA Property - if any

  • fkey: the SA ForeignKey or None

  • pkey: True is field is a PRIMARY KEY or False

Other attributes

  • widget: the widget used to represent it. May be sqlkit.widgets.mask.miniwidget or similar
  • format: the format used to represent the field (numeric or date/time)
  • locale: the locale to use to represent the field (numeric or date/time)
  • DecimalFields also have precision/scale
  • Varchar/TextFields also have blank=True/False (default: False). It determines if an empty string is a valid value. Empty strings are differerent from NULL values

future

This should provide a way to set the possible observers

validation based on the type should live here

possibly more validation may live here

formatting/locale

see decimal to have an intro on formatting numbers

FieldChooser

This class implements a way to determine which Field should be associated to each field_name in a mapper (used in setup_field_validation so that it can be easily overwritten). It’s important to understand that it already receives a gtkwidget from layoutgenerator; that widget has been set by introspection of the layout description and of the field in the database.

You can overwrite the decision of the field redefining the gui_field on a derived sqlwidget or passing it as argument (see code snippet 34):

class Movie(SqlMask):
    gui_field_mapping = {'date_release' : VarcharField}

t = Movie(table='movie', dbproxy=db, layout=lay)

It’s up to the field defined in this way to be able to handle the type of data. This setting can be used to add field constraints (eg: mail address validation) or to completely change the widget that represent data.

Widgets

A Field does not create a gtk widget to represent data. Layout definition is normally enought to create the correct GTK widget. If a gtk widget exists that represent a field, it is handled by a proxy called Miniwidget that offers a common interface to possbly different gtk widgets. If a MiniWidget exists the Field will instantiate it and set values thought it.

A notable exception to this rule is represented by any m2m/o2m relation, that in the layout is only present as a gtk.Alignment widget to which a children is added by mask.Widget.

Miniwidgets for all main types are provided.

Global variables

Varchar fields will try to cast an empty value to None unless blank_ok is set in the field:

t.gui_field.field_name.blank_ok = True

or globally:

from sqlkit.widgets.common import fields fields.BLANK_OK = True

Default value for BLANK_OK is False.

This is only enforced for NEW records, for already persisted records the default behaviour is to let it as-is, to prevent a very annoying flood of dialog “do you want to save?” when you just need to browse some data.

Available Fields

class sqlkit.fields.Field(field_name, field_attrs=None)
set_widget(gtkwidget=None, def_str=None, widget=None)
Parameters:
  • def_str – the definition string in the layout that determined the gtk.Widget (eg.: c=married, e=first_name)
  • widget – the miniwidget to be used. Defaults to class-defined self.Widget the widget can be a string of a Widget derived from miniwidget.Widget
  • gtkwidget – the gtk widget to be used (already created by Layout)
set_value(value, initial=True, shown=False, obj=None, update_widget=True)

Set the value

Parameters:
  • value – the value to be set. It will be cleaned.
  • initial – if True the self.initial_value is set as. self.initial_value is used to know if a field has changed
  • obj – if passed the attribute is set on the object when the field is set
  • update_widget – if True (default) the widget that renders the field is set as well.
get_value(shown=False)
Return the current value. Look for it in the widget and returns a cleaned value
clear_value()
sets a value that clears the corresponding widget, can be None or []
format_value(value, format=None)

return a string representation of the value according to current locale value is a”cleaned” value

Parameter:value – the value to be formatted (must already be casted to correct type)
clean_value(value, obj=None)

return a value of the correct type, if needed parse it with locale parsers (numbers, date...)

Parameters:
  • value – the value to be cleaned (i.e. casted to correct type). It’s the attribute of a persisten object or the object itself for non persisted fields. I.e.: if you create a custom field to count how many movies has directed each director, the Director instance will be passed as value.
  • obj – the object to which the field belongs. It’s normally disreguarded but it can be used by special fields (as image fields) to create customized property (e.g.: the save path)

This function is used while sorting a column

has_changed(verbose=False)
return True if field has changed after last set
get_default()
return the default value for this object
validate(value, clean=False)
check if the current value is accepted and call on_field__validation on the master’s hook.
get_human_value(value, format=None)
return the value or a translation in human readable for foreign key

All other field inherit from Field

class sqlkit.fields.VarcharField(*args, **kw)

The field to represent Strings

blank_ok
The widget return an epty string on empty values. This variable determines if that value will be set NULL or left empty. Regardless of this value the value is left untouched if it already exists.
class sqlkit.fields.IntegerField(*args, **kw)

The fields to handle interegers

format
How to represent integers. Default: ‘#,###’
class sqlkit.fields.FloatField(*args, **kw)

The fields to handle floats

format
How to represent integers. Default: None
class sqlkit.fields.DecimalField(*args, **kw)

The fields to handle Numeric Fields

format
How to represent integers. Default: ‘#,###.00’ (The number of 0 determined by scale
class sqlkit.fields.TextField(*args, **kw)
class sqlkit.fields.DateField(*args, **kw)

The fields to handle datets

format
The format used to represent dates. Default: short
class sqlkit.fields.TimeField(*args, **kw)
The fields to handle times w/o timezone
class sqlkit.fields.TimeTZField(*args, **kwargs)
The fields to handle times with timezone
class sqlkit.fields.IntervalField(field_name, field_attrs=None)
The fields to handle times with interval
class sqlkit.fields.DateTimeField(*args, **kwargs)
The fields to handle datetimes w/o timezone
class sqlkit.fields.DateTimeTZField(*args, **kwargs)
The fields to handle datetimes with timezone
class sqlkit.fields.BooleanField(field_name, field_attrs=None)
A field to handle booleans that does not allow NULL
class sqlkit.fields.BooleanNullField(field_name, field_attrs=None)
A field to handle booleans that allows NULL
class sqlkit.fields.EnumField(*args, **kw)

A field to handle a set of allowed values. You set values in the info column dict or setting values. Setting info column’s key render to ‘enum’ triggers this field and a widget based on ComboBox. It doesn’t currently use Sqlalchemy Enum type as it’s not yet supported in sqlalchemy 0.5.

keys
A list of allowe values in the orederd set by the programmer. Used to set the order of the Combo Box
values
A dict: keys are the allowed values, values are te corresponding descriptions. It’s up to the programmer to set this list appropriately.
lookup_value(value)
Return the value to be shown
class sqlkit.fields.ImageField(*args, **kw)

Imge field suitable for VarcharField that hold an image path and should be rendered as image (icon in tables). It’s never used when autoloading the database schema (no info on the database tells that a string represent an image path), it can be forced setting info values on the Column:

render:         image
base_dir:       a directory
thumbnail_size: tuple (width, height)
default_size:   tuple (width height)

as in:

image = Column(String(100), info={'render' : 'image', 'base_dir' : '/path/to/images'}

Image field that can create a thumbnail and resize an image into jpeg/png format using gtk.gdk.pixbuf* functions

base_dir
base directory under which all files will be saved. Default is os.getcwd() unless is set at Schema time as shown above. get_save_path() will use this to create a complete path. This can be set when defining the Column as shown above.
thumbnail_size
size of the thumbnail used to render in treeview. Default 50,50. Can be set in Column.info as explained above.
default_size
If set it must be a tuple (width, height) and all uploaded files will be default to these dimentions if bigger.
get_value(shown=False, complete_path=False)

Return the path to the image

Parameters:
  • shown – boolean: not meaningful for this field
  • complete_path – boolean: compose it with base path
set_value(value, initial=True, shown=False, obj=None, update_widget=True, new_name=None)

Set the value and -if needed- copy the image file inside base_dir possibly resizing it to default_size. When resizing the only possible format is jpeg and the name is changed accordingly.

Parameters:
  • value – the value to be set. It will be cleaned.
  • initial – if True the self.initial_value is set as. self.initial_value is used to know if a field has changed
  • obj – if passed the attribute is set on the object when the field is set
  • update_widget – if True (default) the widget that renders the field is set as well.
clean_value(value, obj=None)
strip self.base_dir from the file if present
get_save_path(name=None, obj=None, new=False)

Return a standard save path. You may want to customize it.

Parameters:
  • name – the name of the file as picked up from the filesystem or the desired new name for the file. clean_value() call this also for already save path.
  • obj – the object. This may be used to work out the path. It’s not used by default.
  • new – if True, the obj is currently uploaded, name mangle should happen
scale_pixbuf(pixbuf, width=None, height=None)

scale pixbuf image with the same ratio so that it fits into self.w/self.h

Parameters:
  • pixbuf – the pixbuf to scale
  • width – the desider width
  • height – the desider height
scale_file(image_path, dst_path, width, height)
Scale input file into output file. Keep width/height ratio :param image_path: path of the image to resize :param dst_path: new name of the image :param width: the desired width :param height: the desired height
create_thumbnail(filename, thumbnail_path=None)

Create a thumbnail that will be used when rendering images in tables. Uses attribute thumbnail_size

Parameter:filename – the filename to create a thumbnail for
get_thumbnail(path=None, complete_path=False)

Return a thumbnail path and create the thumbnail image, if it doesn’t already exists

Parameters:
  • path – the path of the image file. If missing it’s found using get_value()
  • complete_path – return a complete path. Default is to return the path stripped from the base_dir
get_thumbnail_path_with_size(filename)

Return the thumbnail name for filename using default size. Place the thumbnail in a subdir of image dir ‘.thumbnail’ used by get_thumbnail() and create_thumbnail(). The name contains the thumbail_size used to generate it.

Parameter:filename – the complete filename of the image
class sqlkit.fields.ForeignKeyField(*args, **kwargs)

A field to handle foreign keys

lookup_value(field_value)
retrieve the value in a lookup table in case of foreign_key. It means: “given the foreign key return a value describing at the best the referenced record”. This implies some guessing of the best representation of the record or using information given to site-wide database configuration via _sqlkit_table. The details of such mechanism are described in Completion and Table Description. Since field_value may be incorrectly casted (it is used in completion) errors are catched and None is returned (rather than raising an Error)

Add an object to fullfill the constraint on delete-orphan

This is not meant to be used directly, it is used by set_value() If you have a relation with a delete-orphan constraint that would complain that is not attached to anybody configure the Column adding in the info keyword the attach_instance key pointing to the property of the relation to be added.

In the demo you can find this example:

class Movie(Base):
    __tablename__  = 'movie'
    ...
    director_id    = Column(Integer, ForeignKey('director.id'), nullable=False,
                            info={'attach_instance': 'director'})

class Director(Base):
    __tablename__ = 'director'
    ...
    movies      = relation('Movie', backref='director', cascade='all, delete-orphan',)

Attaching a director_id via completion, requires that you attach a director instance as well.

class sqlkit.fields.CollectionField(*args, **kwargs)
A field that manages a collection of objects Used in OneToMany or ManyToMany db fields. it’s default widget is a collectionWidget that uses a SqlTable
sqlkit.fields.std_cleanup(fn)

A decorator that will handle standard cases: value is None, is a string or is already cleaned.

This is handy when building new Fields as it allows to keep the .clean_value method as simple as possible, i.e. no need to check for standard cases:

class CountMovies(fields.IntegerField):
    '''
    A field that counts the movies
    '''
    @fields.std_cleanup
    def clean_value(self, value):
        ## missing a field_name attribute on obj the object itselt is passed
        return len(value.movies)