On Thursday 28 February 2013, Aymeric Augustin wrote: > > I would support renaming them to first / last through a deprecation path. > The new aliases would be available immediately, the old ones would be > removed in two versions. > +1
> And while we're there, I suggest to rely on the existing "ordering" meta > attribute and to remove "get_latest_by". I suspect that in many cases > these two attributes have the same value, and you can specify an explicit > ordering otherwise. Consistent with the above, +1 and as far as Wim's original question is concerned: > Which style do you prefer? > > .filter(last_name__startswith='b').order_by('last_name').first() # clear > and long > .first(last_name__startswith='b').order_by('last_name') # first method > has filter syntax. > .filter(last_name__startswith='b').first('last_name') # first method has > order_by syntax. ordering is given by position, filtering by keyword arguments -- why not support both? def first (self, *ordering, **filtering): ... My only concern is one that Anssi raised -- the check for multiple objects is discarded, and there is no convenient way to get 0-or-1 objects (which is the semantics of the try-get-except-DoesNotExist-return-None pattern this is designed to replace). I don't think it has been given enough attention in the discussion so far. One option -- with my suggested syntax -- is that if no ordering is given, then it means only one is expected (and, say, None could be used to say "use default ordering"). I suspect, though, that this might be a confusing (and conflated) interface. Or maybe it can be saved by saying you must use one or the other but not both; then it's "overloaded", but nothing really surprising happens. This way, None could be used to say "No ordering -- there should be only one", which is even more intuitive. We get (semantically): qset.first('last_name') ==> qset.order_by('last_name')[0] if qset.exists() else None qset.first(None) ==> qset.get() if qset,exists() else None qset.first(last_name__startswith='b') ==> qset.filter(last_name__startswith='b').first(None) qset.first("last_name", last_name__startswith='b') ==> raise TypeError("first() takes either all positional args or all keywords") qset.first() ==> qset.first(qset.model.ordering) Note that with this suggestion: qset.filter(a=b).first(c) is not equivalent to qset.order_by(c).filter(a=b) Because the latter checks for multiple objects and the former doesn't; this. IMO, justifies raising a type-error when trying to use both. Shai. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.