fizyk / pyramid_basemodel

Global base classes for Pyramid SQLAlchemy applications.
http://pypi.python.org/pypi/pyramid_basemodel
The Unlicense
14 stars 9 forks source link

A few additions #11

Open zupo opened 8 years ago

zupo commented 8 years ago

Hey @thruflo!

At NiteoWeb we've been using your package for over a year now. During this time we've grown a few of our own utility additions on top of pyramid_basemodel. While some are quite specific to our use-cases, I believe some could be useful for the general public. I'll go through two of them below and ask for your opinion if this is something that could go into pyramid_basemodel, so I start submitting Pull Requests.

  1. "get by" mixins Basically all our classes inherit from these. We have GetByIDMixin, GetByNameMixin, GetByTitleMixin and GetByEmailMixin. These mixins give you the ability to then do MyModel.by_id(1), MyModel.by_name('foo'), MyModel.by_title(u'Foö) and MyModel.by_email('foo@bar.com), respectively. They don't add any fields, just getter methods. Our code has been cleaned up considerably since we started using these.

    Example implementation:

    # Marker object for checking if parameter was passed
    sentinel = object()
    
    class GetByIdMixin(object):
       """A mixin for adding by_id method to models."""
    
       @classmethod
       def by_id(cls, id, default=sentinel):
           """Get a Model object by id."""
           try:
               id = int(id)
               return cls.query.filter_by(id=id).first()
           except (ValueError, TypeError) as exc:
               if default == sentinel:
                   raise exc
               else:
                   return default
  2. repr mixin Set a repr method that returns more meaningful representation for sqlalchemy models. These representations are especially useful in Sentry error reports and live debugging sessions. The fields that are displayed in representation are limited to the fields from mixins above

    Example: MyModel that has fields id, name and title, but not email, would have such a representation: <MyModel:1 (name=foo, title=Foö)>.

zupo commented 8 years ago

I went through the code again and saw that we have a bit different approach to naming.

We use name as URL-safe string and title for unicode string. The pyramid_basemodel uses slug for URL-safe string and name for unicode string. I would have to adjust our mixins to adhere to this naming, but this should not be an issue.

thruflo commented 8 years ago

Hi,

Sorry not to reply sooner. Sounds great to me, please do make a PR if you do have the time.

As you say, I've tended to use slug and name so probably does make sense to use by_slug and by_name. I guess you could also introduce a generic cls.by_attr(attribute_name, value) (although this is basically cls.query.filter_by().first()).

James.