Re: [Future feature?] Viewsets

2013-01-26 Thread Amirouche B.
Héllo Bertrand,

Yesterday I read a Ruby on Rails tutorial and this gave me an idea of what 
> could IMO be a nice feature: viewsets.
> I therefore started a tiny project, 
> django-viewsets 
> (djangonauts 
> have weird reflexes… ^^).  *Everything is explained there.*
>
> What do you think?  Could this be an interesting feature?  “The next level 
> of class-based views”?  A *contrib* application?
>

It's very interesting and it might be why a similar thing exists in the 
admin but not pluggable yet.

There is a ticket for this issue: 
https://code.djangoproject.com/ticket/16213

I made another implementation of this 
https://github.com/django-composite/django-composite/blob/master/composite/urls.py

- It's named UrlCollection since it's a collection of urls...
- Support callable, views function and CBVs
- It's possible to provide a default application_namespace (see 
https://code.djangoproject.com/ticket/11642) but overridable at include time
- It's also possible to nest UrlCollections (equivalent your ViewSets class)
- It's possible to inherit AdminSite and ModelAdmin from UrlCollection and 
implement the missing methods/properties...

But there is no particular support of GCBV (ListView, CreateView...), it's 
a good idea I will add it.

Please have a look at it, I'll do the same with multiviews and viewsets and 
to try to advance the discussion further maybe merge the three of them ?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@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.




Re: Viewsets

2013-01-26 Thread Anssi Kääriäinen
On 26 tammi, 12:49, "Amirouche B." 
wrote:
> Please have a look at it, I'll do the same with multiviews and viewsets and
> to try to advance the discussion further maybe merge the three of them ?

Multiviews is just a proof of concept. If you see something nice in
the concept, then reuse that. Otherwise it is throwaway code.

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@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.




Re: [Future feature?] Viewsets

2013-01-26 Thread Bertrand Bordage
Hello Anssi, Amirouche, and anyone else,

Glad to see I am not the only one that got this idea (nearly at the same 
time, btw)!


Le samedi 26 janvier 2013 11:49:34 UTC+1, Amirouche B. a écrit :
>
> It's very interesting and it might be why a similar thing exists in the 
> admin but not pluggable yet.
>
> There is a ticket for this issue: 
> https://code.djangoproject.com/ticket/16213 
>

OK.  I guess we discuss in this google group until we come up to some 
design decisions, then write it to the ticket?


I made another implementation of this 
> https://github.com/django-composite/django-composite/blob/master/composite/urls.py
>
Please have a look at it, I'll do the same with multiviews and viewsets and 
> to try to advance the discussion further maybe merge the three of them ?
>

Excellent!  I spent two hours reading the code of both multiviews and 
composite.  Here is what I understood:


What's in common between multiviews, composite, and viewsets:

   - Views are grouped in a class.
   - Each view is tied to an URL pattern.
   - All URL patterns of a group of views are accessible using nearly the 
   same syntax: GroupOfViews.urls() for multiviews, url('', 
   include(GroupOfViews().urls())) for composite and url('', 
   include(GroupOfViews().urls)) for viewsets.



Multiviews
Pros:

   - Simple.

Cons:

   - Uses inspect to find views.  Too "magic" IMO.
   - Requires to define a form, specify the namespace and template names 
   (example: https://github.com/akaariai/multiviews/blob/master/views.py#L96
   ).
   - The views defined are very simple reimplementations of GCBV; and of 
   course, not extensible.
   - No GCBV support. 



Composite
Pros:

   - Powerful; a complete framework to the glory of Python (write less 
   HTML/CSS/JS, more Python!) and DRY.
   - Views directly have name and path attributes to avoid writing them 
   inside urls.py.

Cons:

   - Complex.
   - Highly misleading names (especially Widget…).
   - No application namespace detection.
   - Can't be easily merged in Django (I know, composite was not designed 
   for this purpose).



Viewsets
Pros:

   - Simple.
   - Designed to be extensible (even though it could be better).
   - Automatic application namespace based on model app_labels.
   - PEP8 compliance and Python3 support ;o)

Cons:

   - No function-based views support (could be fixed in two lines).
   - Uses an awkward dict to define views, url names and patterns.



By the way, I really liked in *composite* the idea of setting url names and 
patterns as class-based view attributes.
Maybe the best idea of all this discussion; could this become a core 
feature, as well as "template_name" and "get_template_name"?


Thanks,
Bertrand

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@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.




Re: A.objects.getdefault

2013-01-26 Thread Mike Fogel
+1 to replacing earliest() and latest() with order_by('field').first() and 
.last(), respectively. I'm not a fan of the implied semantics of 'earliest' 
and 'latest' - as if they only worked with time-based fields.

Mike

On Tuesday, January 22, 2013 3:03:22 PM UTC-8, Wim Feijen wrote:
>
> Hi Selwin and Anssi,
>
> Anssi, thanks for improving the patch and getting it ready for commit! 
>
> Selwin, you are right that .filter() and .first() are very similar. 
> Rationale for .first() is to get rid of the pattern 
> try: 
> instance = ModelX.objects.get 
> except ObjectDoesNotExist:
> instance = None
> , which is a very common pattern so an exception seems out of place. Using 
> filter to get the first result or none would still require three lines. 
> Other alternative patterns are in this thread.
>
> For me, example use cases would be Address.objects.first() which would 
> return the first address in a list, when browsing through all addresses in 
> detail view, or page.music_files.first() where we just have one music file 
> per page or none. MusicFile.objects.first(page=page) should work too.
>
> Indeed, .earliest('timestamp') could be expressed as 
> .order_by('timestamp').first() , and latest similarly. In my opinion these 
> are consistent with .filter() and .get().
>
> Default ordering by id if no order is specified is the same behaviour as 
> in the admin, so I would argue not to raise an exception when no ordering 
> is specified, but to keep it like it is and order by id. Thanks for adding 
> that Anssi!
>
> Looking forward to other input,
>
> Best regards,
>
> Wim
>
>
> On Sunday, 20 January 2013 12:18:22 UTC+1, Selwin Ong wrote:
>>
>> Hi Anssi,
>>
>> Shouldn't first() and last() raise an exception if no ordering is 
>> specified? This keeps it consistent with latest() which requires the user 
>> to explicitly specify what field it wants to use as ordering.
>>
>> Also, like you mentioned, IMHO these APIs are too similar (first, 
>> earliest, last and latest) in name, yet the usage is completely different, 
>> with latest() expecting a field name, the other filter args. What I also 
>> don't like is that the filter_args expected by last() and first() are:
>> 1. Doesn't allow exclude arguments
>> 2. We already have .filter() method which does the same thing (filters a 
>> queryset with passed kwargs)
>>
>> So if I may suggest, I think a better option would be to change the 
>> methods first() and last() to behave more like latest(), but they should 
>> return None when the query returns no result. Example usage:
>>
>> User.objects.exclude(a=b).filter(c=d).first('id') # Returns None if 
>> there's no match
>>
>>  
>>
>> user = User.objects.exclude(a=b).filter(c=d).last('id')
>> if user:
>># do things...
>>
>>
>> If last() and first() are introduced, perhaps we can also deprecate 
>> latest() in the future because they're very similar.
>>
>> What do you guys think?
>>
>> Best,
>> Selwin
>>
>> On Sunday, January 20, 2013 1:51:27 PM UTC+7, Anssi Kääriäinen wrote:
>>>
>>> On 10 tammi, 09:27, Wim Feijen  wrote: 
>>> > Hi, 
>>> > 
>>> > Ticket 19326 has been marked as ready for check-in for some time. Can 
>>> > some-one have a look at it? 
>>> > 
>>> >  https://code.djangoproject.com/ticket/19326 
>>> > 
>>> > Thanks, 
>>> > 
>>> > Wim 
>>>
>>> I did some more polish to the patch. There is now also .last() method, 
>>> and if there is no ordering in the queryset, then it will be 
>>> automatically ordered by the primary key. 
>>>
>>> I didn't commit the patch yet, as I wonder if there will be confusion 
>>> about .latest(by_field), .last(filter_args). earliest(by_field) 
>>> and .first(filter_args)? 
>>>
>>> Currently, the usage is this: 
>>> a = 
>>> Article.objects.order_by('headline').first(pub_date__year=2005) 
>>> which will return first article by headline if any found or None if no 
>>> match. .last() will just change the ordering by first 
>>> calling .reverse() on the qs. 
>>>
>>> The patch is 100% ready for commit as far as I am concerned (cursory 
>>> check of the changes doesn't hurt, of course). So, if one of the BDFLs 
>>> sees the API as fine just go and commit the patch. 
>>>
>>> Patch available from 
>>> https://github.com/akaariai/django/compare/ticket_19326. 
>>>
>>>  - Anssi 
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@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.




Re: A.objects.getdefault

2013-01-26 Thread Selwin Ong
Hi Wim,

I think there's a slight misunderstanding here. I completely agree with you 
that .first() and .last() should return None if there's no matching row :). 
The syntax I proposed:

User.objects.exclude(a=b).filter(c=d).first('id')  # Returns None if 
there's no matching row
User.objects.order_by('id').exclude(a=b).filter(c=d).first()  # Does 
the same thing as above

Best,
Selwin


On Wednesday, January 23, 2013 6:03:22 AM UTC+7, Wim Feijen wrote:
>
> Hi Selwin and Anssi,
>
> Anssi, thanks for improving the patch and getting it ready for commit! 
>
> Selwin, you are right that .filter() and .first() are very similar. 
> Rationale for .first() is to get rid of the pattern 
> try: 
> instance = ModelX.objects.get 
> except ObjectDoesNotExist:
> instance = None
> , which is a very common pattern so an exception seems out of place. Using 
> filter to get the first result or none would still require three lines. 
> Other alternative patterns are in this thread.
>
> For me, example use cases would be Address.objects.first() which would 
> return the first address in a list, when browsing through all addresses in 
> detail view, or page.music_files.first() where we just have one music file 
> per page or none. MusicFile.objects.first(page=page) should work too.
>
> Indeed, .earliest('timestamp') could be expressed as 
> .order_by('timestamp').first() , and latest similarly. In my opinion these 
> are consistent with .filter() and .get().
>
> Default ordering by id if no order is specified is the same behaviour as 
> in the admin, so I would argue not to raise an exception when no ordering 
> is specified, but to keep it like it is and order by id. Thanks for adding 
> that Anssi!
>
> Looking forward to other input,
>
> Best regards,
>
> Wim
>
>
> On Sunday, 20 January 2013 12:18:22 UTC+1, Selwin Ong wrote:
>>
>> Hi Anssi,
>>
>> Shouldn't first() and last() raise an exception if no ordering is 
>> specified? This keeps it consistent with latest() which requires the user 
>> to explicitly specify what field it wants to use as ordering.
>>
>> Also, like you mentioned, IMHO these APIs are too similar (first, 
>> earliest, last and latest) in name, yet the usage is completely different, 
>> with latest() expecting a field name, the other filter args. What I also 
>> don't like is that the filter_args expected by last() and first() are:
>> 1. Doesn't allow exclude arguments
>> 2. We already have .filter() method which does the same thing (filters a 
>> queryset with passed kwargs)
>>
>> So if I may suggest, I think a better option would be to change the 
>> methods first() and last() to behave more like latest(), but they should 
>> return None when the query returns no result. Example usage:
>>
>> User.objects.exclude(a=b).filter(c=d).first('id') # Returns None if 
>> there's no match
>>
>>  
>>
>> user = User.objects.exclude(a=b).filter(c=d).last('id')
>> if user:
>># do things...
>>
>>
>> If last() and first() are introduced, perhaps we can also deprecate 
>> latest() in the future because they're very similar.
>>
>> What do you guys think?
>>
>> Best,
>> Selwin
>>
>> On Sunday, January 20, 2013 1:51:27 PM UTC+7, Anssi Kääriäinen wrote:
>>>
>>> On 10 tammi, 09:27, Wim Feijen  wrote: 
>>> > Hi, 
>>> > 
>>> > Ticket 19326 has been marked as ready for check-in for some time. Can 
>>> > some-one have a look at it? 
>>> > 
>>> >  https://code.djangoproject.com/ticket/19326 
>>> > 
>>> > Thanks, 
>>> > 
>>> > Wim 
>>>
>>> I did some more polish to the patch. There is now also .last() method, 
>>> and if there is no ordering in the queryset, then it will be 
>>> automatically ordered by the primary key. 
>>>
>>> I didn't commit the patch yet, as I wonder if there will be confusion 
>>> about .latest(by_field), .last(filter_args). earliest(by_field) 
>>> and .first(filter_args)? 
>>>
>>> Currently, the usage is this: 
>>> a = 
>>> Article.objects.order_by('headline').first(pub_date__year=2005) 
>>> which will return first article by headline if any found or None if no 
>>> match. .last() will just change the ordering by first 
>>> calling .reverse() on the qs. 
>>>
>>> The patch is 100% ready for commit as far as I am concerned (cursory 
>>> check of the changes doesn't hurt, of course). So, if one of the BDFLs 
>>> sees the API as fine just go and commit the patch. 
>>>
>>> Patch available from 
>>> https://github.com/akaariai/django/compare/ticket_19326. 
>>>
>>>  - Anssi 
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@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.