entity.py
changeset 7827 9bbf83f68bcc
parent 7816 a8a424a78c26
child 7828 749e1a67987f
equal deleted inserted replaced
7821:3ecd114f6d75 7827:9bbf83f68bcc
    30 from rql.stmts import Select
    30 from rql.stmts import Select
    31 from rql.nodes import (Not, VariableRef, Constant, make_relation,
    31 from rql.nodes import (Not, VariableRef, Constant, make_relation,
    32                        Relation as RqlRelation)
    32                        Relation as RqlRelation)
    33 
    33 
    34 from cubicweb import Unauthorized, typed_eid, neg_role
    34 from cubicweb import Unauthorized, typed_eid, neg_role
       
    35 from cubicweb.utils import support_args
    35 from cubicweb.rset import ResultSet
    36 from cubicweb.rset import ResultSet
    36 from cubicweb.selectors import yes
    37 from cubicweb.selectors import yes
    37 from cubicweb.appobject import AppObject
    38 from cubicweb.appobject import AppObject
    38 from cubicweb.req import _check_cw_unsafe
    39 from cubicweb.req import _check_cw_unsafe
    39 from cubicweb.schema import RQLVocabularyConstraint, RQLConstraint
    40 from cubicweb.schema import RQLVocabularyConstraint, RQLConstraint
   138             mixins += cls.__bases__[1:]
   139             mixins += cls.__bases__[1:]
   139             cls.__bases__ = tuple(mixins)
   140             cls.__bases__ = tuple(mixins)
   140             cls.info('plugged %s mixins on %s', mixins, cls)
   141             cls.info('plugged %s mixins on %s', mixins, cls)
   141 
   142 
   142     fetch_attrs = ('modification_date',)
   143     fetch_attrs = ('modification_date',)
       
   144 
   143     @classmethod
   145     @classmethod
   144     def fetch_order(cls, attr, var):
   146     def cw_fetch_order(cls, select, attr, var):
   145         """class method used to control sort order when multiple entities of
   147         """This class method may be used to control sort order when multiple
   146         this type are fetched
   148         entities of this type are fetched through ORM methods. Its arguments
   147         """
   149         are:
   148         return cls.fetch_unrelated_order(attr, var)
   150 
       
   151         * `select`, the RQL syntax tree
       
   152 
       
   153         * `attr`, the attribute being watched
       
   154 
       
   155         * `var`, the variable through which this attribute's value may be
       
   156           accessed in the query
       
   157 
       
   158         When you want to do some sorting on the given attribute, you should
       
   159         modify the syntax tree accordingly. For instance:
       
   160 
       
   161         .. sourcecode:: python
       
   162 
       
   163           from rql import nodes
       
   164 
       
   165           class Version(AnyEntity):
       
   166               __regid__ = 'Version'
       
   167 
       
   168               fetch_attrs = ('num', 'description', 'in_state')
       
   169 
       
   170               @classmethod
       
   171               def cw_fetch_order(cls, select, attr, var):
       
   172                   if attr == 'num':
       
   173                       func = nodes.Function('version_sort_value')
       
   174                       func.append(nodes.variable_ref(var))
       
   175                       sterm = nodes.SortTerm(func, asc=False)
       
   176                       select.add_sort_term(sterm)
       
   177 
       
   178         The default implementation call
       
   179         :meth:`~cubicweb.entity.Entity.cw_fetch_unrelated_order`
       
   180         """
       
   181         cls.cw_fetch_unrelated_order(select, attr, var)
   149 
   182 
   150     @classmethod
   183     @classmethod
   151     def fetch_unrelated_order(cls, attr, var):
   184     def cw_fetch_unrelated_order(cls, select, attr, var):
   152         """class method used to control sort order when multiple entities of
   185         """This class method may be used to control sort order when multiple entities of
   153         this type are fetched to use in edition (eg propose them to create a
   186         this type are fetched to use in edition (e.g. propose them to create a
   154         new relation on an edited entity).
   187         new relation on an edited entity).
       
   188 
       
   189         See :meth:`~cubicweb.entity.Entity.cw_fetch_unrelated_order` for a
       
   190         description of its arguments and usage.
       
   191 
       
   192         By default entities will be listed on their modification date descending,
       
   193         i.e. you'll get entities recently modified first.
   155         """
   194         """
   156         if attr == 'modification_date':
   195         if attr == 'modification_date':
   157             return '%s DESC' % var
   196             select.add_sort_var(var, asc=False)
   158         return None
       
   159 
   197 
   160     @classmethod
   198     @classmethod
   161     def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X',
   199     def fetch_rql(cls, user, restriction=None, fetchattrs=None, mainvar='X',
   162                   settype=True, ordermethod='fetch_order'):
   200                   settype=True, ordermethod='fetch_order'):
   163         st = cls.fetch_rqlst(user, mainvar=mainvar, fetchattrs=fetchattrs,
   201         st = cls.fetch_rqlst(user, mainvar=mainvar, fetchattrs=fetchattrs,
   274                 else:
   312                 else:
   275                     fetchattrs = etypecls.fetch_attrs
   313                     fetchattrs = etypecls.fetch_attrs
   276                 etypecls._fetch_restrictions(var, select, fetchattrs,
   314                 etypecls._fetch_restrictions(var, select, fetchattrs,
   277                                              user, ordermethod, visited=visited)
   315                                              user, ordermethod, visited=visited)
   278             if ordermethod is not None:
   316             if ordermethod is not None:
   279                 orderterm = getattr(cls, ordermethod)(attr, var.name)
   317                 try:
   280                 if orderterm:
   318                     cmeth = getattr(cls, ordermethod)
   281                     var, order = orderterm.split()
   319                     warn('[3.14] %s %s class method should be renamed to cw_%s'
   282                     select.add_sort_var(select.get_variable(var), order=='ASC')
   320                          % (cls.__regid__, ordermethod, ordermethod),
       
   321                          DeprecationWarning)
       
   322                 except AttributeError:
       
   323                     cmeth = getattr(cls, 'cw_' + ordermethod)
       
   324                 if support_args(cmeth, 'select'):
       
   325                     cmeth(select, attr, var)
       
   326                 else:
       
   327                     warn('[3.14] %s should now take (select, attr, var) and '
       
   328                          'modify the syntax tree when desired instead of '
       
   329                          'returning something' % cmeth, DeprecationWarning)
       
   330                     orderterm = cmeth(attr, var.name)
       
   331                     if orderterm is not None:
       
   332                         try:
       
   333                             var, order = orderterm.split()
       
   334                         except ValueError:
       
   335                             if '(' in orderterm:
       
   336                                 self.error('ignore %s until %s is upgraded',
       
   337                                            orderterm, cmeth)
       
   338                                 orderterm = None
       
   339                             elif not ' ' in orderterm.strip():
       
   340                                 var = orderterm
       
   341                                 order = 'ASC'
       
   342                         if orderterm is not None:
       
   343                             select.add_sort_var(select.get_variable(var),
       
   344                                                 order=='ASC')
   283 
   345 
   284     @classmethod
   346     @classmethod
   285     @cached
   347     @cached
   286     def _rest_attr_info(cls):
   348     def _rest_attr_info(cls):
   287         mainattr, needcheck = 'eid', True
   349         mainattr, needcheck = 'eid', True