Hi everyone,

I have a problem in tg2 displaying records in turbogears
Administration System. I created two tables and a view in this way:

adresses (table):

address_id
str_number
street
unit_type
unit number
city
state
post_code

persons (table):

person_id
first_name
last_name
dob
address_id

there is a foreign key from adresses.address_id on persons.address_id

persons_view

person_id
first_name
last_name
dob
address = addresses.str_number +' '+ addresses.street+'
'+addresses.city (defined in postgresql database in the appropriate
way, || instead of +)

my model/__init__.py looks like (reflected tables and a view):

# -*- coding: utf-8 -*-
"""The application's model objects"""

from zope.sqlalchemy import ZopeTransactionExtension
from sqlalchemy.orm import scoped_session, sessionmaker

from sqlalchemy.orm import mapper,  relation
from sqlalchemy import Table

from sqlalchemy.ext.declarative import declarative_base

maker = sessionmaker(autoflush=True, autocommit=False,
                     extension=ZopeTransactionExtension())
DBSession = scoped_session(maker)

DeclarativeBase = declarative_base()
metadata = DeclarativeBase.metadata

class Persons(object):
    def  __init__ (self,  **kw):
        for key,  value in kw.iteritems():
            setattr(self,  key,  value)

class Persons_view(object):
    def __init__(self,  **kw):
        for key,  value in kw.iteritems():
            setattr(self,  key,  value)

class Addresses(object):
    def __init__(self,  **kw):
        for key,  value in kw.iteritems():
            setattr(self,  key,  value)

def init_model(engine):
    """Call me before using any of the tables or classes in the
model."""
    DBSession.configure(bind=engine)

    persons_table = Table('persons',  metadata,  autoload=True,
autoload_with=engine)
    mapper(Persons,  persons_table)

    addresses_table = Table('addresses',  metadata,  autoload=True,
autoload_with=engine)
    mapper(Addresses,  addresses_table)

    persons_view = Table('persons_view',  metadata,  autoload=True,
autoload_with=engine)
    mapper(Persons_view,  persons_view,  primary_key=
[persons_view.c.person_id])

# Import your model modules here.
from problem.model.auth import User, Group, Permission

To quickstarted controllers/root.py I added:

from problem.model import Addresses, Persons, Persons_view
from problem.controllers.test import test

and in RootController:

   admin_alternative = test

Here is my controllers/test.py:

# -*- coding: utf-8 -*-
"""Sample controller module"""

# turbogears imports
from tg import expose
from tgext.crud import CrudRestController
from tg import redirect, validate, flash, config
from tw.core import WidgetsList
from tw.forms import *
#from formencode import validators
from formencode.validators import *

# Admin Controller imports
from tgext.admin import AdminController, AdminConfig,
CrudRestControllerConfig
#from upute import model


# third party imports
from pylons.i18n import ugettext as _
from repoze.what import predicates

# project specific imports
from upute.lib.base import BaseController
from problem import model
from problem.model import *
from sprox.tablebase import TableBase
from sprox.fillerbase import TableFiller, EditFormFiller
from sprox.formbase import AddRecordForm, EditableForm
from sprox.dojo.tablebase import DojoTableBase
from sprox.dojo.fillerbase import DojoTableFiller

__all__= ['test_kontroler']

# Creatin a list of items for SingleSelectField

def comboBox(redovi, polje_sifra, polja_lista):
    lista=[(None, None),]
    for red in redovi:
        red_lista=[]
        for polje in polja_lista:
            i=red.__getattribute__(polje)
            if type(i) is not unicode:
                i=unicode(i)
            red_lista.append(i)
        red_string = u" ".join(red_lista)
        lista.append((red.__getattribute__(polje_sifra), red_string))
    return lista


class Persons_form(TableBase):
    __model__ = Persons
    __omit_fields__ = ['person_id']
    __field_order__ = ['last_name', 'first_name', 'dob']
    __headers__ = {'last_name' : 'Last Name',
                    'first_name' : 'First Name',
                    'dob' : 'Date of Birth',
                    'address_id' : 'Address_ID'}

class Persons_filler(TableFiller):
    __model__ = Persons

class Persons_view_form(DojoTableBase):
    __model__ = Persons_view
    __omit_fields__ = ['person_id']
    __field_order__ = ['last_name', 'first_name', 'dob']
    __headers__ = {'last_name' : 'Last Name',
                    'first_name' : 'First Name',
                    'dob' : 'Date of Birth',
                    'address' : 'Address'}

class Persons_view_filler(DojoTableFiller):
    __model__ = Persons_view

class Persons_add_form(AddRecordForm):
    def addresses(): return comboBox(DBSession.query
(Addresses).order_by(Addresses.str_number), 'address_id',
['str_number', 'street', 'city', 'state'])
    __model__           = Persons
    __require_fields__  = []
    __omit_fields__     = ['person_id']
    __field_order__     = ['last_name', 'first_name', 'dob',
'address_id']
    # Overrided Fields
    address_id = SingleSelectField('address_id', label=_(u'Address'),
options=addresses)

class Persons_edit_form(EditableForm):

    def addresses(): return comboBox(DBSession.query
(Addresses).order_by(Addresses.str_number), 'address_id',
['str_number', 'street', 'city', 'state'])

    __model__           = Persons
    __require_fields__  = []
    __omit_fields__     = ['sifra_podnositelja']
    __field_order__     = ['ime', 'prezime', 'spol', 'mbg', 'oib',
'datum_rod', 'mjesto_rod', 'zemlja_rod', 'prebivaliste', 'boraviste',
'tel', 'fax', 'e-mail', 'odnos_prema_osobi', 'sifra_osobe']
    # Overrided Fields
    address_id = SingleSelectField('address_id', label=_(u'Address'),
options=addresses)

class Persons_edit_filler(EditFormFiller):
    __model__ = Persons


class Persons_config(CrudRestControllerConfig):
    table_type = Persons_form
    table_filler_type = Persons_filler
    # table_type = Persons_view_form
    # table_filler_type = Persons_view_filler
    new_form_type = Persons_add_form
    edit_form_type = Persons_edit_form
    edit_filler_type = Persons_edit_filler


class Configuration(AdminConfig):
    persons = Persons_config

test = AdminController(model, DBSession, config_type=Configuration)


When I go to http://localhost:8088/admin_alternative/personss instead
of a record a get "No records found" despite the fact there are
records. When I subclass Persons_form and Persons_filler from
DojoTableForm and reapectively, DojoTableFiller I can see the record.
Then I tried using persons_view instead of persons (so I would have
meaningfull address instead of address_id) so class Persons_config
looks like:

class Persons_config(CrudRestControllerConfig):
    #table_type = Persons_form
    #table_filler_type = Persons_filler
    table_type = Persons_view_form
    table_filler_type = Persons_view_filler
    new_form_type = Persons_add_form
    edit_form_type = Persons_edit_form
    edit_filler_type = Persons_edit_filler

but after refreshing the page instead of records I get:
"Sorry, an error occurred"

and debug view gave me:

WebError Traceback:
⇝ TypeError: getattr(): attribute name must be string
View as:   Interactive (full)  |  Text (full)  |  XML (full)
clear this
clear this
URL: http://192.168.8.15:8088/admin_alternative/personss.json?start=0&count=20
Module weberror.evalexception:431 in respond         view
<<          try:
                   __traceback_supplement__ =
errormiddleware.Supplement, self, environ
                   app_iter = self.application(environ,
detect_start_response)

                   # Don't create a list from a paste.fileapp object
>>  app_iter = self.application(environ, detect_start_response)
Module tg.configuration:655 in wrapper         view
<<              log.debug("Making request body seekable")
                   Request(environ).make_body_seekable()
               return app(environ, start_response)
           return wrapper
>>  return app(environ, start_response)
Module tg.configuration:555 in remover         view
<<          def remover(environ, start_response):
                   try:
                       return app(environ, start_response)
                   finally:
                       log.debug("Removing DBSession from current
thread")
>>  return app(environ, start_response)
Module repoze.tm:19 in __call__         view
<<              return start_response(status, headers, exc_info)
               try:
                   result = self.application(environ,
save_status_and_headers)
               except:
                   self.abort()
>>  result = self.application(environ, save_status_and_headers)
Module repoze.who.middleware:107 in __call__         view
<<          wrapper = StartResponseWrapper(start_response)
               app_iter = app(environ, wrapper.wrap_start_response)

               # The challenge decider almost(?) always needs
information from the
>>  app_iter = app(environ, wrapper.wrap_start_response)
Module tw.core.middleware:43 in __call__         view
<<      def __call__(self, environ, start_response):
               return self.wsgi_app(environ, start_response)

           def wsgi_app(self, environ, start_response):
>>  return self.wsgi_app(environ, start_response)
Module tw.core.middleware:68 in wsgi_app         view
<<              else:
                       # Pass request downstream
                       resp = req.get_response(self.application)
                   return resp(environ, start_response)
               finally:
>>  resp = req.get_response(self.application)
Module webob:1325 in get_response         view
Module webob:1293 in call_application         view
Module tw.core.resource_injector:68 in _injector         view
<<      def _injector(environ, start_response):
               req = Request(environ)
               resp = req.get_response(app)
               content_type = resp.headers.get('Content-Type','text/
plain').lower()
               if 'html' in content_type:
>>  resp = req.get_response(app)
Module webob:1325 in get_response         view
Module webob:1293 in call_application         view
Module beaker.middleware:81 in __call__         view
<<
self.cache_manager)
               environ[self.environ_key] = self.cache_manager
               return self.app(environ, start_response)
>>  return self.app(environ, start_response)
Module beaker.middleware:160 in __call__         view
<<                          headers.append(('Set-cookie', cookie))
                   return start_response(status, headers, exc_info)
               return self.wrap_app(environ, session_start_response)

           def _get_session(self):
>>  return self.wrap_app(environ, session_start_response)
Module routes.middleware:130 in __call__         view
<<                  environ['SCRIPT_NAME'] = environ['SCRIPT_NAME']
[:-1]

               response = self.app(environ, start_response)

               # Wrapped in try as in rare cases the attribute will be
gone already
>>  response = self.app(environ, start_response)
Module pylons.wsgiapp:125 in __call__         view
<<
               controller = self.resolve(environ, start_response)
               response = self.dispatch(controller, environ,
start_response)

               if 'paste.testing_variables' in environ and hasattr
(response,
>>  response = self.dispatch(controller, environ, start_response)
Module pylons.wsgiapp:324 in dispatch         view
<<          if log_debug:
                   log.debug("Calling controller class with WSGI
interface")
               return controller(environ, start_response)

           def load_test_env(self, environ):
>>  return controller(environ, start_response)
Module problem.lib.base:32 in __call__         view
<<          request.identity = request.environ.get
('repoze.who.identity')
               tmpl_context.identity = request.identity
               return TGController.__call__(self, environ,
start_response)
>>  return TGController.__call__(self, environ, start_response)
Module pylons.controllers.core:221 in __call__         view
<<                  return response(environ, self.start_response)

               response = self._dispatch_call()
               if not start_response_called:
                   self.start_response = start_response
>>  response = self._dispatch_call()
Module pylons.controllers.core:172 in _dispatch_call         view
<<              req.environ['pylons.action_method'] = func

                   response = self._inspect_call(func)
               else:
                   if log_debug:
>>  response = self._inspect_call(func)
Module pylons.controllers.core:107 in _inspect_call         view
<<                        func.__name__, args)
               try:
                   result = self._perform_call(func, args)
               except HTTPException, httpe:
                   if log_debug:
>>  result = self._perform_call(func, args)
Module tg.controllers:857 in _perform_call         view
<<                  return
                   result = DecoratedController._perform_call(
                       self, controller, params, remainder=remainder)

               except HTTPException, httpe:
>>  self, controller, params, remainder=remainder)
Module tg.controllers:172 in _perform_call         view
<<                          remainder[i] = params[name]
                               del params[name]
                   output = controller(*remainder, **dict(params))

               except formencode.api.Invalid, inv:
>>  output = controller(*remainder, **dict(params))
Module ?:2 in get_all         view
Module tg.decorators:560 in with_trailing_slash         view
<<          from tg.controllers import redirect
               redirect(request.url+'/')
           return func(*args, **kwargs)

       #{ Authorization decorators
>>  return func(*args, **kwargs)
Module tgext.crud.controller:92 in get_all         view
Module sprox.dojo.fillerbase:23 in get_value         view
<<              order_by = order_by[1:]
                   desc = True
               items = super(DojoTableFiller, self).get_value(value,
limit=limit, offset=offset, order_by=order_by, desc=desc, **kw)
               count = self.get_count()
               identifier = self.__provider__.get_primary_field
(self.__entity__)
>>  items = super(DojoTableFiller, self).get_value(value, limit=limit, 
>> offset=offset, order_by=order_by, desc=desc, **kw)
Module sprox.fillerbase:201 in get_value         view
<<                          value = getattr(self, field)(obj, **kw)
                           else:
                               value = getattr(self, field)(obj)
                       else:
                           value = getattr(obj, field)
>>  value = getattr(self, field)(obj)
Module sprox.fillerbase:155 in __actions__         view
<<          """Override this function to define how action links
should be displayed for the given record."""
               primary_fields = self.__provider__.get_primary_fields
(self.__entity__)
               pklist = '/'.join(map(lambda x: str(getattr(obj, x)),
primary_fields))
               value = '<div><div>&nbsp;<a href="'+pklist+'/edit"
style="text-decoration:none">edit</a>'\
                     '</div><div>'\
>>  pklist = '/'.join(map(lambda x: str(getattr(obj, x)), primary_fields))
Module sprox.fillerbase:155 in <lambda>         view
<<          """Override this function to define how action links
should be displayed for the given record."""
               primary_fields = self.__provider__.get_primary_fields
(self.__entity__)
               pklist = '/'.join(map(lambda x: str(getattr(obj, x)),
primary_fields))
               value = '<div><div>&nbsp;<a href="'+pklist+'/edit"
style="text-decoration:none">edit</a>'\
                     '</div><div>'\
>>  pklist = '/'.join(map(lambda x: str(getattr(obj, x)), primary_fields))
TypeError: getattr(): attribute name must be string


I have 2 questions:

1. Why does not a form subclassed from TableBase and TableFiller show
records
2. What is the difference in showing records from a table compared to
showing records from a view


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to