Lesson 5 : Using relations¶
Download lesson [here]
In this lesson we use a simple relation.
We create a user rights scheme for persons wishing to use some resources - cars in this case. The collection schema looks like this:
person_collection link_collection car_collection
+--------------------+ +------------------+ +--------------------+
| _id |<-+ | _id | +->| _id |
| name | +---| user_key | | | brand |
| surname | | car_key |---+ | year |
| | | drive | | |
| | | sell | | |
+--------------------+ +------------------+ +--------------------+
An entry in the link_collection gives a person the right to use a certain car.
In the user interface, user can choose a person and a car and grant user rights by pressing the “NEW” button on the right.
import sys
# from PyQt5 import QtWidgets, QtCore, QtGui # Qt5
from PySide2 import QtWidgets, QtCore, QtGui
from cute_mongo_forms.column import LineEditColumn, ComboBoxColumn, ForeignKeyColumn, CheckBoxColumn
from cute_mongo_forms.row import ColumnSpec, Row
from cute_mongo_forms.container import List, FormSet, EditFormSet, PermissionFormSet
from cute_mongo_forms.db import SimpleCollection
Create the column patters (Rows) for each collection.
class PersonRow(Row):
columns=[
ColumnSpec(LineEditColumn, key_name="name", label_name="First Name"),
ColumnSpec(LineEditColumn, key_name="surname",label_name="Last Name")
]
person_collection=SimpleCollection(
filename="persons.db",
row_classes=[PersonRow]
)
person_collection.clear()
class CarRow(Row):
columns=[
ColumnSpec(LineEditColumn, key_name="brand",label_name="Brand"),
ColumnSpec(LineEditColumn, key_name="year", label_name="Year")
]
car_collection=SimpleCollection(
filename="cars.db",
row_classes=[CarRow]
)
car_collection.clear()
Here we are referencing to foreign keys. The ForeignKeyColumn column type is a special column that’s not visualized in the form widget (“label_name” is missing). It’s only used for referencing records in other collections:
class LinkRow(Row):
columns=[
ColumnSpec(ForeignKeyColumn, key_name="user_key", collection=person_collection),
ColumnSpec(ForeignKeyColumn, key_name="car_key", collection=car_collection),
ColumnSpec(CheckBoxColumn, key_name="drive", label_name="Can drive"),
ColumnSpec(CheckBoxColumn, key_name="sell", label_name="Can sell")
]
link_collection=SimpleCollection(
filename="links.db",
row_classes=[LinkRow]
)
link_collection.clear()
Create lists and forms for each collection.
In Lists, just define how a record is visualized in the list.
class PersonList(List):
def makeLabel(self,entry):
try:
return entry["name"]+" "+entry["surname"]
except KeyError:
return "?"
class CarList(List):
def makeLabel(self,entry):
try:
return entry["brand"]
except KeyError:
return "?"
The main Qt program. PermissionFormSet is a special FormSet class for handling rights through link tables.
class MyGui(QtWidgets.QMainWindow):
def __init__(self,parent=None):
super(MyGui, self).__init__()
self.initVars()
self.setupUi()
def initVars(self):
# add persons to the collection
person_collection.new(PersonRow,{"name":"Antti","surname":"Mykkanen"})
person_collection.new(PersonRow,{"name":"Jonne","surname":"Paananen"})
person_collection.new(PersonRow,{"name":"Juho", "surname":"Kokkonen"})
person_collection.new(PersonRow,{"name":"Janne","surname":"Suhonen" })
# add cars to the collection
car_collection.new(CarRow,{"brand":"Ford","year":2000})
car_collection.new(CarRow,{"brand":"Audi","year":1996})
car_collection.new(CarRow,{"brand":"Seat","year":2004})
car_collection.new(CarRow,{"brand":"Yugo","year":1985})
car_collection.new(CarRow,{"brand":"BMW", "year":2016})
def setupUi(self):
# self.setGeometry(QtCore.QRect(100,100,800,800))
self.w=QtWidgets.QWidget(self)
self.setCentralWidget(self.w)
self.lay=QtWidgets.QHBoxLayout(self.w)
# List view of person_collection
self.person_lis=PersonList(collection=person_collection)
self.person_lis.widget.setParent(self.w)
self.lay.addWidget(self.person_lis.widget)
# Form views of individual records in the person_collection
self.person_form=FormSet(collection=person_collection)
self.person_form.widget.setParent(self.w)
self.lay.addWidget(self.person_form.widget)
# List view of car_collection
self.car_lis=CarList(collection=car_collection)
self.car_lis.widget.setParent(self.w)
self.lay.addWidget(self.car_lis.widget)
# Form view of records in car_collection
self.car_form=FormSet(collection=car_collection)
self.car_form.widget.setParent(self.w)
self.lay.addWidget(self.car_form.widget)
# Form view of the Link table
self.permission_form=PermissionFormSet(collection=link_collection, key1_name="user_key", key2_name="car_key")
self.permission_form.widget.setParent(self.w)
self.lay.addWidget(self.permission_form.widget)
# Create connections between list views, forms, etc.
self.person_lis.widget. currentItemChanged. connect(self.person_form.chooseForm_slot) # inform person formset about the item in question
self.car_lis.widget. currentItemChanged. connect(self.car_form. chooseForm_slot) # inform car formset about the item in question
# Connect the user/car pair to the permission form
self.person_lis.widget. currentItemChanged. connect(self.permission_form.chooseRecord1_slot) # inform formset about the item in question
self.car_lis.widget. currentItemChanged. connect(self.permission_form.chooseRecord2_slot) # inform formset about the item in question
Start the main Qt program
if (__name__=="__main__"):
app=QtWidgets.QApplication([])
gui=MyGui()
gui.show()
app.exec_()