Same as before, but with alternateID's.
db_schema.py:
#!/usr/bin/python
from sqlobject import *
import os
conn = connectionForURI("sqlite://" + os.getcwd() + "/database.db")
class Person(SQLObject):
_connection = conn
# attributes
name = StringCol(notNone=True, alternateID=True)
# relationships
toasters = MultipleJoin('Toaster') # Person has one/many Toaster
class Toaster(SQLObject):
_connection = conn
# attributes
color = StringCol(notNone=True, alternateID=True)
# relationship
person = ForeignKey('Person') # Person has one/many Toaster
initialize_db.py:
#!/usr/bin/python from db_schema import * Person.createTable() Toaster.createTable() Person(name="john") Person(name="bob") Toaster(color="blue",person=None) Toaster(color="green",person=None)
person.py:
#!/usr/bin/python
import pygtk
pygtk.require('2.0')
import gtk
from gazpacho.loader.proxy import Proxy
from db_schema import *
from gtk_util import *
class PersonEditor(Proxy):
def __init__(self,person_id):
Proxy.__init__(self, gladefile="person.glade")
# connect to db
self.person = Person.get(person_id)
# name entry
if self.person.name != None:
self.name_entry.set_text(self.person.name)
# toasters treeview
liststore = gtk.ListStore(str,str)
self.toasters_treeview.set_model(liststore)
# column 1 is the toaster id
col1 = gtk.TreeViewColumn('id')
self.toasters_treeview.append_column(col1)
cell1 = gtk.CellRendererText()
col1.pack_start(cell1, True)
col1.set_attributes(cell1, text=0)
# column 2 is the toaster color
col2 = gtk.TreeViewColumn('color')
self.toasters_treeview.append_column(col2)
cell2 = gtk.CellRendererText()
col2.pack_start(cell2, True)
col2.set_attributes(cell2, text=1)
# fill with data
for toaster in self.person.toasters:
liststore.append([str(toaster.id),toaster.color])
def on_window1__destroy(self, window):
gtk.main_quit()
def on_name_entry__changed(self,widget):
self.person.name = widget.get_text()
if __name__ == "__main__":
import sys
assert len(sys.argv) >= 2
person_id = int(sys.argv[1])
app = PersonEditor(person_id)
gtk.main()
person.glade:
<?xml version="1.0" ?>
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="events"></property>
<property name="visible">True</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<child>
<widget class="GtkFrame" id="frame1">
<property name="label" context="True" translatable="True">Person</property>
<property name="events"></property>
<property name="label_xalign">0.0</property>
<property name="visible">True</property>
<child>
<widget class="GtkTable" id="table1">
<property name="events"></property>
<property name="n_rows">1</property>
<property name="n_columns">2</property>
<property name="visible">True</property>
<child>
<widget class="GtkEntry" id="name_entry">
<property name="events"></property>
<property name="can_focus">True</property>
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="name_label">
<property name="label" context="True" translatable="True">name</property>
<property name="events"></property>
<property name="visible">True</property>
</widget>
<packing/>
</child>
</widget>
</child>
</widget>
<packing/>
</child>
<child>
<widget class="GtkFrame" id="frame2">
<property name="label" translatable="True">Toasters</property>
<property name="label_xalign">0.0</property>
<property name="visible">True</property>
<child>
<widget class="GtkTreeView" id="toasters_treeview">
<property name="hadjustment">0.000000 0.000000 204.000000 20.400000 183.600000 204.000000</property>
<property name="vadjustment">0.000000 0.000000 10.000000 1.000000 9.000000 10.000000</property>
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
toaster.py:
#!/usr/bin/python
import pygtk
pygtk.require('2.0')
import gtk
from gazpacho.loader.proxy import Proxy
from db_schema import *
from gtk_util import *
class ToasterEditor(Proxy):
def __init__(self,toaster_id):
Proxy.__init__(self, gladefile="toaster.glade")
# connect to db
self.toaster = Toaster.get(toaster_id)
# color entry
if self.toaster.color != None:
self.color_entry.set_text(self.toaster.color)
# person combo
person_list = [person.name for person in Person.select()]
combo_fill_text(self.person_combo, person_list)
if self.toaster.person != None:
combo_set_from_db(self.person_combo, str(self.toaster.person.name))
def on_window1__destroy(self, window):
gtk.main_quit()
def on_color_entry__changed(self,widget):
self.toaster.color = widget.get_text()
def on_person_combo__changed(self, widget):
person_name = combo_get_value(widget)
person = Person.byName(person_name)
self.toaster.personID = person.id
if __name__ == "__main__":
import sys
assert len(sys.argv) >= 2
toaster_id = int(sys.argv[1])
app = ToasterEditor(toaster_id)
gtk.main()
toaster.glade:
<?xml version="1.0" ?>
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="events"></property>
<property name="visible">True</property>
<child>
<widget class="GtkFrame" id="frame1">
<property name="label" context="True" translatable="True">Toaster</property>
<property name="events"></property>
<property name="label_xalign">0.0</property>
<property name="visible">True</property>
<child>
<widget class="GtkTable" id="table1">
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="visible">True</property>
<child>
<widget class="GtkComboBox" id="person_combo">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="bottom_attach">2</property>
<property name="top_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="color_entry">
<property name="visible">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="person_label">
<property name="label" translatable="True">person</property>
<property name="visible">True</property>
</widget>
<packing>
<property name="bottom_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="color_label">
<property name="label" translatable="True">color</property>
<property name="visible">True</property>
</widget>
<packing/>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</glade-interface>
gtk_util.py:
import gtk
def combo_fill_text(combo_widget, content_list):
liststore = gtk.ListStore(str)
combo_widget.set_model(liststore)
cell = gtk.CellRendererText()
combo_widget.pack_start(cell, True)
combo_widget.add_attribute(cell, 'text', 0)
for item in content_list:
combo_widget.append_text(item)
def combo_set_from_db(combo_widget, db_item):
list_model = combo_widget.get_model()
iter = list_model.get_iter_first()
while list_model.get_value(iter,0) != db_item:
iter = list_model.iter_next(iter)
combo_widget.set_active_iter(iter)
def combo_get_value(widget):
list_model = widget.get_model()
iter = widget.get_active_iter()
return list_model.get_value(iter,0)