Re: Redis cache support in core

2019-06-20 Thread Loïc Bistuer
I’m also +1 on having it as part of core given how prominent Redis is.

I agree with Aymeric that it shouldn’t be Django’s responsibility to provide or 
wrap advanced Redis functionalities but I think it would be lovely if we at 
least exposed the connection/client as a public API.

Regards,
Loïc

From: "django-developers@googlegroups.com"  
on behalf of Aymeric Augustin 
Reply-To: "django-developers@googlegroups.com" 

Date: Thursday, 20 June 2019 at 15:35
To: "django-developers@googlegroups.com" 
Subject: Re: Redis cache support in core

Hello,

Until now, this feature request was always declined. As a consequence, every 
user who wants Redis has to choose between django-redis and django-redis-cache. 
Considering that Redis must be the most popular cache backend these days, I'm 
in favor of providing an off-the-shelf solution in Django itself. It's unlikely 
to be a large maintenance burden. It will "just work".

I don't know if factoring out common functionality between the memcached and 
redis backends will really make them easier to maintain. We'll end up with 
three modules (key-value, memcached and redis), which will be more complicated 
than two. If we had three similar backends, that would be a strong argument for 
factoring out common functionality. With only two backends, it may not be worth 
the complexity.

To move this forwards, my suggestion would be to write a DEP, to flesh out the 
rationale for a built-in solution, and to focus on the breadth of functionality 
the built-in backend would support. My preference would be a basic set of 
features, like the other cache backends. I believe that's what 
django-redis-cache does. This will leave room for third-party packages like 
django-redis to provide more advanced features. To give a concrete example, 
like other cache and database backends, a redis backend could provide 
persistent connections but not implement a connection pool. Until now Django 
has left the management of connection pools to third-party packages.

Best regards,

--
Aymeric.




On 17 Jun 2019, at 17:11, Dulmandakh Sukhbaatar 
mailto:dulmand...@gmail.com>> wrote:

Hello,

I would like to work on Redis support in core, and I would like to discuss 
proper solution for that.

Redis is getting so popular and almost every modern backend stack uses it 
someway, therefore I think that supporting it as a cache backend in core would 
make Django more appealing. A solution I'm proposing is to extract base KV 
backend from current Memcached and extend it for both Memcached and Redis, and 
this won't add many new code to the core. Also we'll have base class for KV 
storage backends.

Thanks.

--
You received this message because you are subscribed to the Google Groups 
"Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/3a506133-f08a-4d25-a9c5-099aae3722d8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups 
"Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/F93AED93-32FC-4BF4-BDA7-48B4A76A8314%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/SG2PR06MB2618FE99016D6B6AE043C03AA4E40%40SG2PR06MB2618.apcprd06.prod.outlook.com.
For more 

Re: Add an optional parameter to values() that returns a nested dictionary for foreign keys

2016-08-19 Thread Loïc Bistuer
I prefer enforcing .values(alias=F(’something’)), to me 
.values(alias=‘something’) reads as the equivalent of 
.values(alias=Value(‘something’)).

-- 
Loïc

> On Aug 20, 2016, at 1:04 AM, Tim Graham  wrote:
> 
> We now have support for expressions in values()/values_list() -- thanks Ian! 
> With the new commit [0], aliases can be created like this: 
> .values(alias=F('field'))
> 
> Ian has offered an additional commit in the pull request [1] to allow 
> .values(alias='field') (without the F() expression) to automatically wrap the 
> string in an F() expression to create an alias. I'm not sure whether or not 
> to accept that patch as I think I prefer the look of the explicit F() rather 
> than magically treating strings as F() expressions. What do you think?
> 
> [0] 
> https://github.com/django/django/commit/39f35d4b9de223b72c67bb1d12e65669b4e1355b
> [1] https://github.com/django/django/pull/7088
> 
> On Wednesday, November 25, 2015 at 7:24:22 PM UTC-5, Josh Smeaton wrote:
> I would really like two things for values to support.
> 
> 1. Aliases .values(alias='field');
> 2. Expressions .values(alias=F('field'))
> 
> I think these two features are absolute must haves, and the syntaxes above 
> are already standard in other parts of the ORM.
> 
> If someone can come up with a way to support nested relations while 
> supporting the above syntax, then I'd be OK with that. But at the moment, I'm 
> firmly in the "this is the responsibility of a serialiser" camp. I'm not 
> convinced Django needs to support nested objects at all. Is this something 
> you could implement with your own queryset method on a manager? Is this maybe 
> something we could look at creating a new queryset method called 
> .values_dict() ?
> 
> If it weren't for backwards compatibility, I'd suggest that referencing the 
> related object would automatically nest that object. That would differentiate 
> between the id and the field values('related_id', 'related') -> 
> '{"related_id": 1, "related": {"id": 1, ..}}'.
> 
> If there's (rough) consensus on having nested objects, then we could allow 
> something like: .values(..., ..., nested=('related', 
> 'related__otherrelated')). If the value of nested is an iterable then assume 
> we're nesting, otherwise nested is an alias for the field. I don't 
> particularly like overloaded kwargs, but we're just guarding against someone 
> wanting to alias as "nested" which we could call out in docs anyway.
> 
> The more I think about this the more I think nesting and aliases within a 
> nest should probably be done in a different queryset method. Or just handled 
> by a serialiser. If you want more requests per second, then add some more 
> backends.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/00d4305c-175e-415c-b446-a53c7d15c00d%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/C7D98DF5-5F48-4E89-849F-D5E28A93D1DE%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Making max_length argument optional

2016-03-04 Thread Loïc Bistuer
I’m not too keen on a contrib.pg field. CharField is the base class of many 
fields, a __init__ kwarg approach such as max_length=None allows us to reach 
those as well.

> On Mar 5, 2016, at 3:05 AM, Marc Tamlyn  wrote:
> 
> Voting:
> 
> 1) should there be a default?
> 
> I'm lazy, so I would be happy to have one. Where validation matters you can 
> change it, where it doesn't you don't have to. I'd draw an analogy to 
> (Positive)(Small)IntegerField - I often use the normal one when I mean some 
> variant of validation, or some other max/min value.
> 
> 2) how to make it easy to have no limit on PG?
> 
> If it's truly pg specific, then a contrib.pg field seems fine, though 
> probably call it UnlimitedCharField for lack of ambiguity.
> 
> M
> 
> On 1 Mar 2016 1:11 a.m., "Markus Holtermann"  wrote:
> From what I understand you will have a hard time doing that at all:
> 
> On PG could go with a 'max_length=None' in a 3rd party app. But that wouldn't 
> be supported on any other database backend. Which means you're limiting your 
> app to PG. On the other hand you could make your app database independent by 
> using a TextField which has pretty much the same performance on PG as a 
> VARCHAR() and is available on other backends. But may perform bad on other 
> backends. But there's no way to have a text of unlimited length on MySQL 
> other than a TEXT column.
> 
> TL;DR: you can't achieve both ways anyway. Neither now nor if we change the 
> behavior of Django's max_length attribute on CharFields.
> 
> /Markus
> 
> On Tuesday, March 1, 2016 at 11:00:29 AM UTC+11, Cristiano Coelho wrote:
> I find that using TextField rather than CharField just to make postgres use 
> varchar() is a terrible idea, if you are implementing an reusable app and it 
> is used on a backend like MySQL where TextFields are created as text columns 
> which are horribly inneficient and should be avoided at any cost you will 
> have a really bad time.
> I'm not sure about postgres but I want to believe that using varchar without 
> limits has also some performance considerations that should be taken care of.
> 
> El lunes, 29 de febrero de 2016, 17:58:33 (UTC-3), Shai Berger escribió:
> Hi, 
> 
> Thank you, Aymeric, for summing up the discussion this way. The division into 
> two separate problems is indeed required, and I fully support the idea of 
> setting max_length's default to 100 or 120. 
> 
> There seem to be just two points worth adding to your summary: 
> 
> On Monday 29 February 2016 11:19:02 Aymeric Augustin wrote: 
> > 
> > 2) How can we make it easy for PostgreSQL users to just use VARCHAR()? 
> > 
> > Since this is a PostgreSQL-specific feature, having a variant of CharField 
> > in django.contrib.postgres that supports and perhaps even defaults to 
> > unlimited length shouldn’t be controversial. 
> > 
> 
> The first -- I believe it was raised very early on by Christophe Pettus -- is 
> that Django already has a field that manifests on PG as VARCHAR(), and that 
> is 
> TextField. However, I don't like the idea that PG users should be using 
> TextField(widget=TextInput) as a replacement for CharField; I find that 
> counter-intuitive -- even if just because it is a "bad name". Names are 
> important. 
> 
> The second -- in response to a comment made by Josh Smeaton -- is that having 
> django.db.models.CharField with default max_lenth=N (for some finite N) and 
> django.contrib.postgres.CharField with default max_length=None (meaning 
> infinity) sounds like a bad idea. 
> 
> > 
> > I hope this helps! 
> 
> I'm certain it did! 
> 
> Shai. 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/71e5e743-29bb-4dba-9bf4-6948ab2d1fa9%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CAMwjO1Gj3E4_83qdbQmQwXe_WdTXUf7yuZ44-aQ9jgvJN9-5sg%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you 

Re: Making max_length argument optional

2016-02-28 Thread Loïc Bistuer
There is a precedent to this (although it seems to happen at startup time 
rather than save time), we loop through all the connections and check that 
max_length has a value supported by their backend: 
https://github.com/django/django/blob/master/django/db/backends/mysql/validation.py.

I don’t think we need to create a new sentinel value to mean “unlimited” when 
`max_length=None` works well semantically, if we want to keep the `max_length` 
value explicit we can just use `NOT_PROVIDED` as the kwarg default value. It is 
backwards compatible since `max_length=None` currently issues an error.

Regarding the switch to a default value of 120 or so, I don’t have a strong 
opinion against it, but I think it’s an orthogonal problem to supporting 
unlimited varchar on backends that can handle it.

> On Feb 28, 2016, at 6:50 PM, Florian Apolloner  wrote:
> 
> I do not see how blowing up on save is a good idea (especially not if we ran 
> model validation before). We do not do that for MySQL (at least not if your 
> project is configured properly, leaving issues with utf8mb4 out for now) 
> since our model form validation is able to use the supplied max_length to 
> inform the user that the data is invalid __before__ save.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/663F6FA1-1D09-4A21-928A-836157386253%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Making max_length argument optional

2016-02-28 Thread Loïc Bistuer
I don't think this is a problem, we could validate that the backend supports it 
during save then blow up if we detect it doesn't. I think we do that for 
truncation on MySQL. If the model specifies something that the db doesn't 
support it's a configuration problem, not a user validation problem.  

Sent from my iPhone

> On Feb 28, 2016, at 6:23 PM, Florian Apolloner  wrote:
> 
> 
> 
>> On Sunday, February 28, 2016 at 9:57:27 AM UTC+1, Luke Plant wrote:
>> We could also potentially add another sentinel like 
>> DB_MAX_UNICODE_SAFE_LENGTH that works as you expect and is clearly 
>> documented, for the sake of 3rd party apps, and comes with the caveat that 
>> it produces different behaviour on different databases.
> 
> This is simply not an option as someone (I think Aymeric) already pointed 
> out. Technically we do not know DB_MAX_UNICODE_SAFE_LENGTH till the call of 
> model.save (since you can supply a using argument there), this means forms 
> will never know the max length and could not perform any validation.
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/b744bca5-e02e-411e-b9b6-971213aafaa3%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5F8A3D88-9CF4-4800-BA65-61D658EB34F2%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: a standard descriptor signature?

2015-10-25 Thread Loïc Bistuer
+1

> On Oct 25, 2015, at 23:09, charettes  wrote:
> 
> Now that Curtis did all the investigation work I think it wouldn't hurt being 
> consistent here.
> 
> __get__(self, instance, cls=None) and __set__(self, instance, value) look 
> like sane defaults to me.
> 
> Le samedi 24 octobre 2015 18:36:32 UTC-4, Tim Graham a écrit :
> Curtis, or should I say FunkyBob, raised the issue here: 
> https://github.com/django/django/pull/5226
> 
> Currently we have several different signatures:
> 
> def __get__(self, instance, instance_type=None)
> def __get__(self, obj, type=None):
> def __get__(self, instance, type=None)
> def __get__(self, obj, objtype)
> def __get__(self, instance, owner)
> 
> and the Python docs don't seem to have a single preference.
> 
> Curtis proposed:
> """
> * "instance_type" is explicit
> * "cls" is a common convention for passing a class
> * "owner" is in the docs {but so are others}
> * and "type" I think is a bit confusing... 
> 
> So... my preference, upon reflection, would be: def __get__(self, instance, 
> cls=None):
> """
> 
> For set, it's mostly: def __set__(self, instance, value)
> but a couple times: def __set__(self, obj, value)
> 
> Do you think it's worth trying to be consistent or not?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/39cb93c3-a6e5-4deb-b34f-95bd844a764e%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/B22998EC-5FCB-4212-AA2D-A50698F75B6C%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Django ORM query syntax enhancement

2015-10-01 Thread Loïc Bistuer
> On Oct 1, 2015, at 13:38, Anssi Kääriäinen  wrote:
> 
> +1 to not requiring all transforms to handle __underscore__ syntax.

+1

> I think what we want to do is allow users choose which syntax they
> prefer. The idea is that Django will support both JSONExtract('data',
> path=['owner', 'other_pets', 0, 'name']) and
> data__owner__other_pets__0__name out of the box.
> 
> We will also make it possible to support callable transforms. For example:
>filter(Exact(Decode(F('name'), 'utf-8'), Value(u'Бармаглот')))
> is equivalent to
>filter(F('name').decode('utf-8') == Value(u'Бармаглот'))
> 
> The callable transforms syntax will not be a part of Django, but it
> will be possible to create an extension for this (it is actually
> surprisingly easy to do once we have support for expressions in
> filter).

I'm pretty convinced we need a better API / sugar as part of core in the long 
run.

The `filter(Exact(Decode(F('name'), 'utf-8'), Value(u'Бармаглот')))` syntax is 
not pythonic and very hard to decipher, and we've reached the limits of our 
historical double underscore syntax (doesn't support multiple arguments, 
limited to ascii, etc.).

I think the `F('name').decode('utf-8')` syntax is a good candidate for core:

- It's a small extension to the existing F objects, so it's easy to grasp for 
existing Django users.
- It's just a thin sugar on top of the canonical API.
- All the required machinery being already in place (lookup & transform 
registration) the change to Django is minimal.

> - Anssi
> 
> On Thu, Oct 1, 2015 at 4:00 AM, Josh Smeaton  wrote:
>> No, not all Lookups or Transforms are required to handle __underscore__
>> syntax. The entire point of supporting object based lookups is to handle
>> cases that get more complex than a single argument transform or a left and
>> right hand side lookup.
>> 
>> In particular, I think your Decode(utf8) example is a good one. It shows
>> that you could maybe shoehorn multiple arg transforms into the
>> __underscore__ api, but it wouldn't be entirely obvious how to do so. You'd
>> probably need to register partial transformations for each encoding you
>> wanted to support. The contrib.postgres module has (from memory)
>> KeyTransform classes that do a similar thing.
>> 
>> Cheers
>> 
>> 
>> On Thursday, 1 October 2015 02:13:41 UTC+10, Alexey Zankevich wrote:
>>> 
>>> I'll try to turn lookups into expression (will use master branch).
>>> I also have a question. Meanwhile the old query syntax with underscores is
>>> pretty good for simple queries (like Model.objects.filter(name='Bob'), it
>>> gets really ugly for parametrized calls, a new JSONField is a good example
>>> of that:
>>> 
>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
>>> []
>>> 
>>> It will get even more messy if we want to pass a string as a second param
>>> of the func.
>>> 
>>> ex.:
>>> 
>>> 1. filter(Decode(F('name'), 'utf-8'), Value(u'Бармаглот'))   # <- neat
>>> 2. filter(name__decode__utf8=u'Бармаглот')  # <- ?? ambiguous and not nice
>>> at all
>>> 
>>> So question - is it implied all the funcs, transforms and lookups to have
>>> underscore-based equivalent? It can affect the final implementation pretty
>>> much. In my opinion underscore-based equivalent should not be really
>>> required for funcs (the problem doesn't seem to affect transforms as they
>>> will not accept multiple params according to another thread).
>>> 
>>> Thanks,
>>> Alexey
>>> 
>>> 
>>> On Wednesday, September 30, 2015 at 9:19:51 AM UTC+3, Anssi Kääriäinen
>>> wrote:
 
 I don't think we need split-to-subq support for Lookups before we make
 them expressions. Lookups as expressions are usable outside .filter(),
 and we need the split-to-subq support only in .filter(expression).
 
 - Anssi
 
 On Wed, Sep 30, 2015 at 8:46 AM, Josh Smeaton 
 wrote:
> I'm mixing my versions, sorry to those following along. 1.9 has just
> reached
> alpha. Lookups as Expressions should be doable for 1.10 which master is
> currently tracking.
> 
> Cheers
> 
> 
> On Wednesday, 30 September 2015 15:31:24 UTC+10, Josh Smeaton wrote:
>> 
>> The alpha for 1.10 has already been cut, and I'm not sure that the
>> kinds
>> of changes needed here are appropriate to add now that the alpha is
>> out. One
>> could *maybe* make the argument that changing Lookup to an Expression
>> now
>> rather than later is the right move considering Transforms just
>> underwent
>> the same change for 1.10. Personally though, I don't think I have the
>> time
>> right now to do this change. I would support you if you were able, but
>> we'd
>> still be at the mercy of the technical board (I assume) for getting
>> this
>> change in for 1.10.
>> 
>> Do you think Lookup as Expressions requires the subquery/exclude fix
>> you
>> mention above? 

Re: removing FlatPage.enable_comments field?

2015-08-13 Thread Loïc Bistuer
How about we deprecate contrib.flatpages:

- I see people abuse it all the time (do way more with it than they should) 
just because it's in core.

- FlatpageFallbackMiddleware is hardly an example to follow.

- It can easily live as a third-party app.

Thoughts?

-- 
Loïc

> On Aug 12, 2015, at 05:43, Tim Graham  wrote:
> 
> Aymeric raised a ticket [1] noting that the FlatPage.enable_comments field 
> appears in the admin by default, but isn't used anywhere which could be a bit 
> confusing. It seems that django-contrib-comments has a moderation feature 
> where you can specify a field on your model to control how comments are 
> handled [2], so this was presumably used for that. I'm not sure removing the 
> field is a great optional unless we introduce a setting to make the flatpage 
> model swappable (do we want more of those?!) for backwards compatibility. A 
> compromise could be to hide the field in the default ModelAdmin and let those 
> who want it to enable it with a custom ModelAdmin. What do you think?
> 
> [1] https://code.djangoproject.com/ticket/25262
> [2] http://django-contrib-comments.readthedocs.org/en/latest/moderation.html
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/ddffdfa8-9c6c-4d42-a816-1717478313f5%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/A201319D-6EC9-486F-B789-1365B0372A7E%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: default values on database level

2015-07-29 Thread Loïc Bistuer
You could already achieve that by making MyPostgresqlFunction a subclass of 
models.Func, I don't think it's worth supporting alternate syntaxes.

Cheers,
Loïc

> On Jul 29, 2015, at 23:05, Podrigal, Aron  wrote:
> 
> What about db_default allows either a constent eg. 
> db_default=contrib.postgres.functions. or a string 
> "MyCustomPostgresFunction()" and optionaly allowing arguments to be passed to 
> the db function optionally also allowing F() expressions by giving a tuple 
> db_default=('MyPostgresqlFunction()', F('column1'), 'NOW()').
> 
> On Wed, Jul 29, 2015 at 11:58 AM, Podrigal, Aron  
> wrote:
> OK, that makes implementation a lot easier. As the model validation can be 
> done with Model.check() based on the backend given at that time either when 
> running the server or makmigrations.
> 
> On Wed, Jul 29, 2015 at 11:50 AM, Michael Manfre  wrote:
> 
> 
> On Wed, Jul 29, 2015 at 11:42 AM, Podrigal, Aron  
> wrote:
> Hi Loic, 
> 
> Agree with having a db_default kwarg. 
> 
> I am not using multiple databases so no experiance with db routers. So how 
> would should we handle routing between different databases when the 
> db_default value is not compatible with that backend? for example 
> Model.save(using='mysql_db') should we than use the Field.default to generate 
> the default value (which is not how it works today, that the default is 
> computed at instance creation). I would prefer in such a case to rely on the 
> database to handle the situation by omitting that field from the columns 
> list, so mysql for example would set a non nullable varchar column to an 
> empty string, where with other databases it would cause an IntegrityError 
> exception. and that db_default and default kwargs cannot be used togethor.
> 
> 
> If db_default is defined for a field, then it should always be used. If the 
> db_default is invalid for the configured backend, then it will and should 
> break. We shouldn't automatically change db_default to a regular default or 
> do any other magic.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CAGdCwBsHa%2BGXJSB6fay%3DbM%2B-3qV0y5oSuDNd4m05QM1PPdfKrw%40mail.gmail.com.
> 
> For more options, visit https://groups.google.com/d/optout.
> 
> 
> 
> -- 
> Aron Podrigal
> -
> '101', '1110010', '110', '1101110'   '101', '110', '1100100', 
> '1110010', '1101001', '1100111', '111', '1101100'
> 
> P: '2b', '31', '33', '34', '37', '34', '35', '38', '36', '30', '39', '39'
> 
> 
> 
> 
> -- 
> Aron Podrigal
> -
> '101', '1110010', '110', '1101110'   '101', '110', '1100100', 
> '1110010', '1101001', '1100111', '111', '1101100'
> 
> P: '2b', '31', '33', '34', '37', '34', '35', '38', '36', '30', '39', '39'
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CANJp-yjOW72mXpKHiq-MCWkSHxSC%3DnBA_42VFuBVJyKFHMXxpg%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/6708A498-F62B-4651-B52D-B40FD1E47DED%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: default values on database level

2015-07-28 Thread Loïc Bistuer
Hi Aron,

+1 on db defaults as well, I've actually started experimenting on this last 
week. It's a bit tricky because migrations do use db defaults in some 
operations (and drop them once they are done) so we have to ensure that the new 
feature doesn't interfere with them.

However I don't think we should create them by default, instead I propose the 
introduction of a db_default kwarg, which should be either a constant, or an 
expression (e.g. db_default=contrib.postgres.functions.TransactionNow).

Cheers,
Loïc

> On Jul 29, 2015, at 12:04, Podrigal, Aron  wrote:
> 
> I would like to propose making Fields.default to rely on the database 
> generated defaults where possible. This could be implemented by having some  
> constants like fields.CURRENT_TIMESTAMP, etc.  The tricky part here is to 
> detect database backend specific capabilities and have a python equivalent 
> fallback.
> 
> Any thoughts?
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CANJp-yi5%2Bu%3DW8PdUXtcot%2BO8%3Df35dVLbStwVArJhU7gDnaNXoA%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/125BCDAB-728B-4BAA-A8AB-38BA0842B709%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Making max_length argument optional

2015-07-28 Thread Loïc Bistuer
Hi Aron,

I'm +1 on addressing this, I often don't care about max_length, but I still 
want a terse form representation. In my projects I use a subclass of TextField 
that sets a TextInput wiget in its formfield() method. But that's not very 
elegant: it requires a custom field for a common use-case, and it's tightly 
coupled to Django forms (i.e. won't work with other form libraries and non-HTML 
forms).

Now how we address this depends on the meaning we want to give to models fields 
like CharField or TextField, more specifically whether the emphasis is on end 
user's perspective or on mapping 1:1 to database concepts.
 
If we see CharField and TextField as respectively "short/single line field" and 
"long/multiline field" from a user's perspective, then it makes sense to lift 
the max_length requirement and use `db_type='TextField'` when max_length is 
None.

However if we want to stay close to their database equivalents, then we could 
have a display hint on TextField (e.g. TextField(display_multiline=False)) and 
Field.formfield() would use that hint to provide a TextInput widget instead of 
a Textarea.
 
Personally I'd much prefer option 1, it's significantly less verbose and more 
often than not I don't want a length constraint, especially considering that 
there is no performance penalty in doing so with all the databases that I care 
about. Also considering we want first class virtual field support (and plan on 
turning existing concrete fields into virtual fields) I don't think it's a big 
problem to break from the existing models.Field/db types mapping.

Cheers,
Loïc

> On Jul 29, 2015, at 11:27, Podrigal, Aron  wrote:
> 
> Hi,
> 
> I am using postgresql and I prefer my VARCHAR columns not to have a length 
> limit. Is there any particular reason why max_length arg to fields is 
> required. If for  compatibility with other database backends we can have some 
> sane default if it is None.
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CANJp-yjwzpk%2BN2%3D4WWbmj5zu2Gwu67G0Sme1f8xQa%2BKrzSQ2Rw%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/EB67D8D3-1633-4CE7-9A7D-E22FA1EB4A47%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why Django is making migrations for external apps?

2015-07-17 Thread Loïc Bistuer
+1!

Loïc

> On Jul 17, 2015, at 23:30, Andrew Godwin  wrote:
> 
> 
> 
> On Fri, Jul 17, 2015 at 11:19 AM, James Bennett  wrote:
> One option for declaring an app "unmanaged" could be via AppConfig. That's 
> fairly clean, mirrors the way you can already set a model as unmanaged in its 
> Meta declaration, and allows for the end user of the app to override by 
> supplying an AppConfig which will generate migrations (should they, for some 
> use-case reason, want that).
> 
> Now this I like.
> 
> Andrew 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CAFwN1uq8bhij2WABvrRW7QPuMcCwVg6d7qKiuMREh2Udb8vNpA%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/297BE194-C7D1-4228-955D-6BAD106E86E9%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: 1.9 release planning

2015-06-23 Thread Loïc Bistuer

> On Jun 23, 2015, at 17:24, Aymeric Augustin 
>  wrote:
> 
> I'm against making changes to the version numbers we've already planned for 
> and also against 1.10, 1.11 etc. version numbers.
> 
> Such numbers can easily break version checks that don't expect this case. 
> There's lots of code in the wild with version checks, some of which will 
> probably behave incorrectly.

I'm not very sympathetic to code that relies on undefined behaviours, 
especially when people have 2 releases to prepare for the change. We'd properly 
document it in the 1.10 release notes.

> Besides, honestly, 1.10 is just ugly :-)

I don't really see anything wrong with 1.10+ versions but maybe that's because 
this scheme is commonplace in libraries that I've used. The 2.0 and 2.1 
exceptions to the new policy are even uglier to me and already introduced a 
fair amount of confusion to people reviewing the proposals.

Also I really like that Django 2.0 would coincide with dropping support for 
Python 2. That's most certainly the biggest backwards incompatibility we'll 
ever have :)

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/76292589-2340-46DB-BB4D-F38414332B2D%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: 1.9 release planning

2015-06-22 Thread Loïc Bistuer
We can just leave RemovedInDjango20Warning as an alias (not a subclass) to 
PendingDeprecationWarning in 1.8. As long as we don't refer to it in the rest 
of the codebase it isn't ambiguous.

-- 
Loïc

> On Jun 23, 2015, at 00:21, Collin Anderson <cmawebs...@gmail.com> wrote:
> 
> People import the warning in order to silence them, right?
> 
> On Monday, June 22, 2015 at 1:19:51 PM UTC-4, Markus Holtermann wrote:
> +1 -- Going with 1.8, 1.9, 1.10, 1.11 (LTS), 2.0 sounds like a solid 
> plan. I don't think any of the (Pending)DeprecationWarnings are much of 
> a public API. I've never seen them in the wild. 
> 
> /Markus 
> 
> On Mon, Jun 22, 2015 at 11:20:52AM -0400, Michael Manfre wrote: 
> >+1. I really don't like the idea of 2.x being odd. 
> > 
> >On Mon, Jun 22, 2015 at 10:33 AM, Loïc Bistuer <loic.b...@gmail.com> 
> >wrote: 
> > 
> >> Just when we thought we had a winner... I'd like to make a final proposal. 
> >> 
> >> Instead of delaying adoption of SemVer to 3.0 we could do so in 2.0 by 
> >> introducing the 1.10 and 1.11LTS releases. 
> >> 
> >> The upside is that the new policy applies right away and we avoid the 
> >> oddball 2.0 and 2.1 releases. 
> >> 
> >> It's much less invasive than the previous idea of renaming 1.9 to 2.0, but 
> >> it still requires renaming PendingDeprecationWarnings in 1.8, and both 
> >> warnings in 1.9. 
> >> 
> >> What do you think? 
> >> 
> >> -- 
> >> Loïc 
> >> 
> >> > On Jun 17, 2015, at 08:47, Josh Smeaton <josh.s...@gmail.com> wrote: 
> >> > 
> >> > I'm also +1 on the proposal as it stands, and neutral on when the semver 
> >> versioning should begin. 
> >> > 
> >> > On Wednesday, 17 June 2015 05:03:47 UTC+10, Michael Manfre wrote: 
> >> > I'm +1 on the Google doc proposal and like Markus, I support relabeling 
> >> 1.9 to 2.0 to line the versions up with the new paradigm without the X.1 
> >> LTS oddball. 
> >> > 
> >> > Regards, 
> >> > Michael Manfre 
> >> > 
> >> > On Tue, Jun 16, 2015 at 12:34 PM, Collin Anderson <cmawe...@gmail.com> 
> >> wrote: 
> >> > I also like the gdoc as it is. (1.8 LTS, 1.9, 2.0, 2.1 LTS, 3.0, 3.1, 
> >> 3.2 LTS, 4.0, etc.) LTS is the final of a major version number, and we 
> >> sacrifice a little bit of strict semver, but it give some nice meaning to 
> >> the version numbers. 
> >> > 
> >> > 
> >> > On Tuesday, June 16, 2015 at 12:22:44 PM UTC-4, Carl Meyer wrote: 
> >> > Thanks Loïc, 
> >> > 
> >> > On 06/16/2015 01:15 AM, Loïc Bistuer wrote: 
> >> > > I've attempted to summarize the history of this thread. Note that I 
> >> > > marked as +1 any generally positive feedback towards a given 
> >> > > proposal, please correct if you feel misrepresented. 
> >> > > 
> >> > [snip] 
> >> > > 
> >> > > # Third iteration: 
> >> > > 
> >> > > 5/ Switching to Semantic Versioning 
> >> > > 
> >> > > Donald mentioned SemVer on IRC a few days ago. Since then various 
> >> > > proposal were made to reconcile it with our release policy. So far 
> >> > > Collin, Carl, Loïc, Tim, and Josh have expressed positive feedback to 
> >> > > various proposals in that direction but I don't think we have yet 
> >> > > reached consensus on a specific one. Tim updated the Google doc to 
> >> > > reflect my latest proposal, so including me that's 2 formal +1 for 
> >> > > it, but I'd say we should wait for at least a couple more votes 
> >> > > before taking it to the technical board. 
> >> > > 
> >> > > Refs: - http://semver.org/ - Carl's analysis 
> >> > > 
> >> https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/Ojov2QBROg8J 
> >> > > 
> >> > > 
> >> > - Ryan's proposals 
> >> > 
> >> https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/lBLWrhKJ6DIJ 
> >> > > - Loïc's proposal 
> >> > > 
> >> https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/y2QbPVzSs6cJ 
> >> > 
> >> > FWIW, I am also +1 on your proposal, as currently documented in the 
> >> > Google doc. 
> >> > 
> >> > I was trying to come up with a proposal where LTS == 

Re: 1.9 release planning

2015-06-22 Thread Loïc Bistuer
Just when we thought we had a winner... I'd like to make a final proposal.

Instead of delaying adoption of SemVer to 3.0 we could do so in 2.0 by 
introducing the 1.10 and 1.11LTS releases.

The upside is that the new policy applies right away and we avoid the oddball 
2.0 and 2.1 releases.

It's much less invasive than the previous idea of renaming 1.9 to 2.0, but it 
still requires renaming PendingDeprecationWarnings in 1.8, and both warnings in 
1.9.

What do you think?

-- 
Loïc

> On Jun 17, 2015, at 08:47, Josh Smeaton <josh.smea...@gmail.com> wrote:
> 
> I'm also +1 on the proposal as it stands, and neutral on when the semver 
> versioning should begin.
> 
> On Wednesday, 17 June 2015 05:03:47 UTC+10, Michael Manfre wrote:
> I'm +1 on the Google doc proposal and like Markus, I support relabeling 1.9 
> to 2.0 to line the versions up with the new paradigm without the X.1 LTS 
> oddball.
> 
> Regards,
> Michael Manfre
> 
> On Tue, Jun 16, 2015 at 12:34 PM, Collin Anderson <cmawe...@gmail.com> wrote:
> I also like the gdoc as it is. (1.8 LTS, 1.9, 2.0, 2.1 LTS, 3.0, 3.1, 3.2 
> LTS, 4.0, etc.) LTS is the final of a major version number, and we sacrifice 
> a little bit of strict semver, but it give some nice meaning to the version 
> numbers.
> 
> 
> On Tuesday, June 16, 2015 at 12:22:44 PM UTC-4, Carl Meyer wrote:
> Thanks Loïc, 
> 
> On 06/16/2015 01:15 AM, Loïc Bistuer wrote: 
> > I've attempted to summarize the history of this thread. Note that I 
> > marked as +1 any generally positive feedback towards a given 
> > proposal, please correct if you feel misrepresented. 
> > 
> [snip] 
> > 
> > # Third iteration: 
> > 
> > 5/ Switching to Semantic Versioning 
> > 
> > Donald mentioned SemVer on IRC a few days ago. Since then various 
> > proposal were made to reconcile it with our release policy. So far 
> > Collin, Carl, Loïc, Tim, and Josh have expressed positive feedback to 
> > various proposals in that direction but I don't think we have yet 
> > reached consensus on a specific one. Tim updated the Google doc to 
> > reflect my latest proposal, so including me that's 2 formal +1 for 
> > it, but I'd say we should wait for at least a couple more votes 
> > before taking it to the technical board. 
> > 
> > Refs: - http://semver.org/ - Carl's analysis 
> > https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/Ojov2QBROg8J 
> > 
> > 
> - Ryan's proposals 
> https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/lBLWrhKJ6DIJ 
> > - Loïc's proposal 
> > https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/y2QbPVzSs6cJ 
> 
> FWIW, I am also +1 on your proposal, as currently documented in the 
> Google doc. 
> 
> I was trying to come up with a proposal where LTS == major release for 
> the sake of argument, since it seemed like that was intuitive to at 
> least some people, but it's not worth the required lengthening of 
> deprecation paths. Your proposal is much better. (And it does make some 
> intuitive sense for the _last_ minor release in a major series to be LTS 
> rather than the first). 
> 
> Carl 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-develop...@googlegroups.com.
> To post to this group, send email to django-d...@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/ebc7b0ae-27aa-4848-a6b5-9cec4b374895%40googlegroups.com.
> 
> For more options, visit https://groups.google.com/d/optout.
> 
> 
> 
> -- 
> GPG Fingerprint: 74DE D158 BAD0 EDF8
> keybase.io/manfre
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/79aae5a5-58dd-4f05-a6dd-35685e06ebb5%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscri

Re: 1.9 release planning

2015-06-16 Thread Loïc Bistuer
I've attempted to summarize the history of this thread. Note that I marked as 
+1 any generally positive feedback towards a given proposal, please correct if 
you feel misrepresented.


# First iteration:

1/ Release every 8 months (previously undefined).

2/ LTS every 3rd releases (previously undefined but effectively 1.8 is the 4th 
release after 1.4). Thanks to point 1/ it means one LTS release every two years.

3/ LTS releases are supported for 3 years (previously undefined). Combined with 
points 1/ and 2/ this gives us 1 year of support overlap between 2 LTS 
(currently we committed as an afterthought to 6 months overlap between 1.4 LTS 
and 1.8 LTS).

Core +1: Tim, Marc, Markus, Collin, Aymeric, Loïc


# Second iteration:

4/ Deprecation shims must appear in a LTS release before being dropped.

So far this is the only real change in the policy, first iteration only 
adjusted and/or pinned variables.

In practice, thanks to point 2/, this only requires one exception to our 
current policy: features deprecated in the release *immediately following* an 
LTS have to be supported for 1 extra release. (e.g 1.9 
PendingDeprecationWarning, 2.0 PendingDeprecationWarning, 2.1 
DeprecationWarning). In return this makes it easier for 3rd-party apps to 
straddle 2 LTS releases without writing their own shims (provided their code 
runs without deprecation warnings on the oldest LTS).

Core +1: Collin, Carl, Tim, Anssi, Michael, Loïc

Refs:
- django-compat thread 
(https://groups.google.com/d/topic/django-developers/ASnZ5Uyol6Y/discussion)
- Collin's proposal 
https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/hou67ofj3EYJ and 
the 7 following responses.


# Third iteration:

5/ Switching to Semantic Versioning

Donald mentioned SemVer on IRC a few days ago. Since then various proposal were 
made to reconcile it with our release policy. So far Collin, Carl, Loïc, Tim, 
and Josh have expressed positive feedback to various proposals in that 
direction but I don't think we have yet reached consensus on a specific one. 
Tim updated the Google doc to reflect my latest proposal, so including me 
that's 2 formal +1 for it, but I'd say we should wait for at least a couple 
more votes before taking it to the technical board.

Refs:
- http://semver.org/
- Carl's analysis 
https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/Ojov2QBROg8J
- Ryan's proposals 
https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/lBLWrhKJ6DIJ
- Loïc's proposal 
https://groups.google.com/d/msg/django-developers/MTvOPDNQXLI/y2QbPVzSs6cJ

Cheers

-- 
Loïc

> On Jun 16, 2015, at 02:37, Aymeric Augustin 
>  wrote:
> 
> If we're approaching consensus, could a kind soul put together a final 
> proposal and submit it to the technical board, along with the main arguments 
> or alternatives? I'm finding it difficult to follow this 50-message thread... 
> Thanks :-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/B8FE1DF4-1542-465B-B3DE-A7CA0DE5C3BB%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: 1.9 release planning

2015-06-15 Thread Loïc Bistuer
I'm -0 (borderline -1) on that proposal. I don't think we should compromise on 
our historical commitment of deprecating over 2 releases, especially since it's 
aligned with the policy of Python itself and much of the ecosystem.

It should be as easy as possible for 3rd-party apps to straddle 2 LTS releases, 
but when it comes to user projects we should make it as easy as possible to 
keep up with the latest stable. Sticking to LTS versions deprive you from up to 
three years of innovation in Django, IMO it's only appropriate for projects in 
maintenance mode. Our current policy allows you to take advantage of new 
features right away while having almost a year and a half to deal with 
deprecations.

The only additional overhead of my counterproposal is an extra 8 months of 
support for features deprecated in an LTS for a total of 16 months. Considering 
non-LTS releases require between 16 months and 24 months I think it's very 
manageable.

Regarding timeline for adoption, I prefer switching right away but I'm also 
happy with a 2.1 > 3.0 switch, so whatever is more popular. Also it shouldn't 
get lost because regardless of the SemVer decision we'll need to update 
RemovedInDjango21Warning in master.

> On Jun 15, 2015, at 19:37, Josh Smeaton <josh.smea...@gmail.com> wrote:
> 
> I really like Ryan's second proposal (quoting here again):
> 
> 2.2 - 0 mos - (LTS) No features dropped 
> 3.0 - 8 mos - All deprecations, including the LTS deprecations, are removed 
> 3.1 - 16 mos - No features dropped 
> 3.2 - 24 mos - (LTS) No features dropped 
> 4.0 - 32 mos - All deprecations, including the LTS deprecations, are removed 
> 4.1 - 40 mos - No features dropped 
> 4.2 - 48 mos - (LTS) No features dropped
> 
> It'll mean that the maximum time a feature can be supported while deprecating 
> is 2 years. The shortest it can be supported is a single release if the 
> deprecation is made in an LTS - which I think is fine because the LTS is 
> supported for 3 years anyway. It perfectly adheres to semver (which is a nice 
> property, but not the be-all and end-all), and still allows libraries to 
> straddle two LTS releases. Is there a good reason we couldn't use this model?
> 
> And I agree with Tim that changing the version numbers of already planned 
> releases is not a good idea. The version naming can wait until the current 
> Removed* warnings are gone - and timing it with the Python 3 only release 
> sounds like a fairly good motivation to bump the major version and continue 
> with semver from there. Provided we remember/document the plan :)
> 
> On Sunday, 14 June 2015 09:58:41 UTC+10, Tim Graham wrote:
> Of course RemovedInDjango19Warning is also in 1.7 and a lot of docs reference 
> Django 1.9. I'm not enthusiastic about updating all that.
> 
> On Sunday, June 14, 2015 at 1:43:50 AM UTC+2, Loïc Bistuer wrote:
> 
> > On Jun 13, 2015, at 20:43, Tim Graham <timog...@gmail.com> wrote: 
> > 
> > I don't have a strong opinion either way on semver, but I think it's a bit 
> > late to rebrand 1.9 as 2.0 considering we've release code and docs with 
> > reference to "RemovedInDjango19Warning". Do you have any thoughts on that? 
> > We could plan the change for after the next LTS (2.1 -> 3.0) to correspond 
> > with the cutover to Python 3. 
> 
> 
> Currently we have: 
> 
> 1.8: 
> RemovedInDjango19Warning(DeprecationWarning) - Deprecations from 1.7 
> RemovedInDjango20Warning(PendingDeprecationWarning) - Deprecations from 
> 1.8 
> 
> master: 
> RemovedInDjango20Warning(DeprecationWarning) - Deprecations from 1.8 
> RemovedInDjango21Warning(PendingDeprecationWarning) - Deprecations from 
> master 
> 
> In any case, implementing the new policy will require updating warnings from 
> master: RemovedInDjango21Warning needs to become either 
> RemovedInDjango22Warning or RemovedInDjango31Warning with the switch to 
> SemVer. 
> 
> The question is whether it's too invasive to update warnings in a 1.8 patch 
> release. If we ensure that RemovedInDjango19Warning remains importable by 
> aliasing it to RemovedInDjango20Warning(DeprecationWarning), I think it's 
> compatible enough not to delay implementing the scheme by another two years, 
> especially considering how warnings are normally used. But if we want to be 
> super cautious we could just leave the code as it is and document the problem 
> in the 1.8 release notes, after all we are extending the lifespan of the 
> shims (at least in appearance) which isn't as problematic as if we were 
> shortening it. 
> 
> -- 
> Loïc 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" group.

Re: 1.9 release planning

2015-06-13 Thread Loïc Bistuer

> On Jun 13, 2015, at 20:43, Tim Graham  wrote:
> 
> I don't have a strong opinion either way on semver, but I think it's a bit 
> late to rebrand 1.9 as 2.0 considering we've release code and docs with 
> reference to "RemovedInDjango19Warning". Do you have any thoughts on that? We 
> could plan the change for after the next LTS (2.1 -> 3.0) to correspond with 
> the cutover to Python 3.


Currently we have:

1.8:
RemovedInDjango19Warning(DeprecationWarning) - Deprecations from 1.7
RemovedInDjango20Warning(PendingDeprecationWarning) - Deprecations from 1.8

master:
RemovedInDjango20Warning(DeprecationWarning) - Deprecations from 1.8
RemovedInDjango21Warning(PendingDeprecationWarning) - Deprecations from 
master

In any case, implementing the new policy will require updating warnings from 
master: RemovedInDjango21Warning needs to become either 
RemovedInDjango22Warning or RemovedInDjango31Warning with the switch to SemVer.

The question is whether it's too invasive to update warnings in a 1.8 patch 
release. If we ensure that RemovedInDjango19Warning remains importable by 
aliasing it to RemovedInDjango20Warning(DeprecationWarning), I think it's 
compatible enough not to delay implementing the scheme by another two years, 
especially considering how warnings are normally used. But if we want to be 
super cautious we could just leave the code as it is and document the problem 
in the 1.8 release notes, after all we are extending the lifespan of the shims 
(at least in appearance) which isn't as problematic as if we were shortening it.

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/3B8CE3F8-F39C-49AF-A5B5-7A252E9F7CAD%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: 1.9 release planning

2015-06-13 Thread Loïc Bistuer
Quoting semver.org:

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.

We are only breaking the first rule with backwards incompatible changes that 
don't undergo deprecations, but considering that we do our very best to avoid 
these, I think it's fair enough to just document it as a caveat.

SemVer makes it easier to see at a glance how long you are supposed to support 
Django versions as a 3rd-party app author and where you can rely on shims. It 
also brings more visibility to our efforts to ease straddle two LTS versions 
(supporting shims from LTS+1 for 1 additional release). I think it's enough to 
justify adopting it even if we aren't "pure" in its implementation.

-- 
Loïc

> On Jun 13, 2015, at 13:03, Tim Graham <timogra...@gmail.com> wrote:
> 
> I'm happy to give it a try if there's consensus that it might help. On the 
> other hand, this doesn't account for the inevitable backwards incompatible 
> changes that come along. For example, someone in the survey said "Django 1.7 
> is a hard change for clients and it should have been 2.0 so that they realize 
> what the jump means." Unfortunately, it's impossible to anticipate when 
> features like that might come along and I'm not sure we'd want to delay 
> features so that they don't first appear in an LTS release (at least, this 
> would be a pretty big change in Django development and slow down innovation 
> in my view).
> 
> On Saturday, June 13, 2015 at 6:25:44 AM UTC-4, Loïc Bistuer wrote:
> I think Collin's proposal can match semver without additional overhead when 
> LTS are the final minor releases of any given major branch. 
> 
> 1.8 LTS 
> 2.0 (Drop features from 1.7) 
> 2.1 (Drop features from 1.8 LTS) 
> 2.2 LTS 
> 3.0 (Drop features from 2.0, 2.1) 
> 3.1 (Drop features from 2.2 LTS) 
> 3.2 LTS 
> 
> That way we can say that features are never removed until the next major 
> release. 
> 
> Features deprecated in a LTS leak onto x.1 releases but that's fine (1 
> release deprecations are a no-go IMO), we can document it as "deprecations 
> from a major branch will be either loud or gone in the following major 
> branch". 
> 
> -- 
> Loïc 
> 
> > On Jun 13, 2015, at 04:16, Tim Graham <timog...@gmail.com> wrote: 
> > 
> > I'm still in favor of "Collin's proposal." You'll need to convince me that 
> > keeping deprecations around longer is worth having somewhat meaningful 
> > version numbers, but I'm not sure I really consider dropping deprecation 
> > shims as "incompatible API changes" that justify a major version bump. For 
> > example, if I run on 2.X (whatever is right before the version where 
> > features are dropped) without deprecation warnings, then upgrading to 3.0 
> > isn't any more difficult than other upgrades. It might be a nice touch to 
> > call the version after the next LTS (2.1 under Collin's proposal) "3.0" 
> > since it will drop Python 2 support, but it's not really important IMO 
> > 
> > On Friday, June 12, 2015 at 8:00:30 PM UTC-4, Ryan Hiebert wrote: 
> > An alternative would be for the LTS to be the second-to-last minor release 
> > before a major version bump. 
> > 
> > I'm also ignoring the transition for the sake of hypotheticals. I'm also 
> > assuming that 2.2 is the last release of the 2.X series. 
> > 
> > 2.1 - 0 mos - (LTS) No features dropped 
> > 2.2 - 8 mos - No features dropped 
> > 3.0 - 16 mos - Drop all features deprecated by 2.1 
> > 3.1 - 24 mos - (LTS) No features dropped 
> > 3.2 - 32 mos - No features dropped 
> > 4.0 - 40 mos - Drop all features deprecated by 3.1 
> > 4.1 - 48 mos - (LTS) No features dropped 
> > 
> > It would mean that features deprecated before an LTS cannot be dropped 
> > until two versions after the LTS, but it fits semver pretty well, and 
> > doesn't speed up our deprecation removal. 
> > 
> > I'd argue for a major version dropping _all_ deprecated features. This has 
> > the downside of speeding up our removal process in the last version of a 
> > major release, and it encourages people to stay longer on the release 
> > previous, since they won't have as much opportunity to fix them. It would 
> > also mean that features deprecated in the last minor version of a major 
> > version line would need to skip the pending deprecation warnings. 
> > 
> > If it were acceptable to do that, then I'd argue for the LTS to be the 
> > _last_ in a major version

Re: 1.9 release planning

2015-06-13 Thread Loïc Bistuer
I think Collin's proposal can match semver without additional overhead when LTS 
are the final minor releases of any given major branch.

1.8 LTS
2.0 (Drop features from 1.7)
2.1 (Drop features from 1.8 LTS)
2.2 LTS
3.0 (Drop features from 2.0, 2.1)
3.1 (Drop features from 2.2 LTS)
3.2 LTS

That way we can say that features are never removed until the next major 
release.

Features deprecated in a LTS leak onto x.1 releases but that's fine (1 release 
deprecations are a no-go IMO), we can document it as "deprecations from a major 
branch will be either loud or gone in the following major branch".

-- 
Loïc

> On Jun 13, 2015, at 04:16, Tim Graham  wrote:
> 
> I'm still in favor of "Collin's proposal." You'll need to convince me that 
> keeping deprecations around longer is worth having somewhat meaningful 
> version numbers, but I'm not sure I really consider dropping deprecation 
> shims as "incompatible API changes" that justify a major version bump. For 
> example, if I run on 2.X (whatever is right before the version where features 
> are dropped) without deprecation warnings, then upgrading to 3.0 isn't any 
> more difficult than other upgrades. It might be a nice touch to call the 
> version after the next LTS (2.1 under Collin's proposal) "3.0" since it will 
> drop Python 2 support, but it's not really important IMO
> 
> On Friday, June 12, 2015 at 8:00:30 PM UTC-4, Ryan Hiebert wrote:
> An alternative would be for the LTS to be the second-to-last minor release 
> before a major version bump. 
> 
> I'm also ignoring the transition for the sake of hypotheticals. I'm also 
> assuming that 2.2 is the last release of the 2.X series. 
> 
> 2.1 - 0 mos - (LTS) No features dropped 
> 2.2 - 8 mos - No features dropped 
> 3.0 - 16 mos - Drop all features deprecated by 2.1 
> 3.1 - 24 mos - (LTS) No features dropped 
> 3.2 - 32 mos - No features dropped 
> 4.0 - 40 mos - Drop all features deprecated by 3.1 
> 4.1 - 48 mos - (LTS) No features dropped 
> 
> It would mean that features deprecated before an LTS cannot be dropped until 
> two versions after the LTS, but it fits semver pretty well, and doesn't speed 
> up our deprecation removal. 
> 
> I'd argue for a major version dropping _all_ deprecated features. This has 
> the downside of speeding up our removal process in the last version of a 
> major release, and it encourages people to stay longer on the release 
> previous, since they won't have as much opportunity to fix them. It would 
> also mean that features deprecated in the last minor version of a major 
> version line would need to skip the pending deprecation warnings. 
> 
> If it were acceptable to do that, then I'd argue for the LTS to be the _last_ 
> in a major version line, rather than the second-to-last. That would probably 
> be my overall preferred, though I do recognize the previously mentioned 
> drawbacks. Anything deprecated in an LTS in that case would skip the pending 
> deprecation warning, and go straight to the deprecation warning. The 
> deprecation timeline would then look like this: 
> 
> 2.2 - 0 mos - (LTS) No features dropped 
> 3.0 - 8 mos - All deprecations, including the LTS deprecations, are removed 
> 3.1 - 16 mos - No features dropped 
> 3.2 - 24 mos - (LTS) No features dropped 
> 4.0 - 32 mos - All deprecations, including the LTS deprecations, are removed 
> 4.1 - 40 mos - No features dropped 
> 4.2 - 48 mos - (LTS) No features dropped 
> 
> 
> I think those are probably the two best LTS support release schedules that 
> follow semver. 
> 
> Ryan
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/f887421b-c470-491f-b5f0-a12af397bfe1%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/2A833F90-C4AA-449F-BF97-B0514FA4F210%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Add support for unsigned primary keys in MySQL

2015-06-10 Thread Loïc Bistuer
I think we can link https://code.djangoproject.com/ticket/56 to 
https://code.djangoproject.com/ticket/14286.

The problem is not so much how to create an UnsignedAutoField or a BigAutoField 
which is rather trivial, but how to deal with foreign keys pointing to them and 
how to migrate them. As far as I know it's the only case where changing one 
field requires migrations in multiple apps, and since you don't necessarily 
have the source repo available for them, it's not clear how we can handle it.

There is also a design issue, do we want AutoField + UnsignedAutoField + 
BigAutoField + UnsignedBigAutoField and their ForeignKey counterparts? That's 
ugly IMO. We could have AutoField(storage=models.IntegerField) which is 
slightly better, or we could wait to have nailed the Virtual/Composite API and 
AutoField would become virtual and use the same API as composite fields to pick 
its backing field (e.g. id = BigIntegerFIeld(); pk = AutoField(concrete='id')).

All in all, I'm not for a wontfix, but as with any low digits tickets a proper 
fix is far from easy.

-- 
Loïc

> On Jun 10, 2015, at 11:50, Markus Amalthea Magnuson 
>  wrote:
> 
> I've picked up this old ticket:
> 
> https://code.djangoproject.com/ticket/56
> 
> After some initial discussions on #django-dev it seems like wontfixing it 
> would be an option too, so I wanted to ask about core devs' view on this:
> 
> Is implementing opt-in support for unsigned primary keys on MySQL still 
> interesting?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CAOXH8SX2gdM3OSDYkY7W94MVac%2Bh9Wo68r2qaRzisbEiYOzhoA%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/76CE4389-DE36-4FBA-9E49-02ED5AFAFF9D%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Introducing django-compat - arteria's solution for for- and backwards compatibility from Django 1.4.x to 1.8.x/1.9.x

2015-06-09 Thread Loïc Bistuer
Thanks Philippe for bringing this up.

I'm currently upgrading a large Django app with dozens of dependencies from 1.4 
to 1.8, here are some observations:
- Most popular and/or maintained libraries actually supports every Django 
version between 1.4 to 1.8. (Many thanks to their maintainers!)
- Libraries that support 1.4 and 1.8 but not with a single version add a lot 
more overhead to the upgrade process.
- Libraries have their own backwards incompatibilities and deprecations. By 
itself it's easily manageable when the new version still support your current 
Django version, but it gets messy when you need to upgrade both Django and 
3rd-party apps at the same time.

Obviously, no production projects should depend on an unsupported version of 
Django, but you still need to upgrade to intermediary versions as you work your 
way to the latest LTS. 3rd-party apps that support both LTS have been a huge 
help to us: you can upgrade them making changes to your project as required, 
then they stay out of the way when you upgrade Django itself. I wouldn't 
consider that libraries still supporting Django 1.5 are encouraging running 
unsupported versions of Django, they are just providing an upgrade path. 
Without such upgrade paths in the Django ecosystem, I think LTS while good on 
paper, are a bad idea in practice. 

The new proposal to have an LTS every third release is an improvement over the 
current situation since 3rd-party apps need to support one less version to 
bridge between two LTS. But I'm not convinced with "deprecated features won’t 
be dropped until the version those features were deprecated in is no longer 
supported"; it adds overhead to Django's maintenance while still requiring 
3rd-party apps to create shims if they want to support both LTS to ease with 
the upgrade process.

How about dropping all the shims in the release immediately following an LTS? 
For example (slightly rewriting the past):
 
1.8 (LTS): No features dropped.
1.9: Dropped features deprecated in 1.4, 1.5, 1.6, 1.7
2.0: No features dropped.
2.1 (LTS): No features dropped.
2.2: Dropped features deprecated in 1.8, 1.9, 2.0

Cheers

-- 
Loïc

> On Jun 3, 2015, at 16:53, Philippe O. Wagner  wrote:
> 
> Thanks Tim for your response and sharing the report of the survey.
> 
> As mentioned in the introduction, we will (give our best to) keep aligned to 
> the official releases and do not intend to bypass the security concept of 
> Django.
> We will update the project README to communicate the concept correctly. 
> https://github.com/arteria/django-compat/issues/28
> 
> Compatibility seems to be common issue. For internal use, we are interested 
> in work from LTS to LTS. For our open source apps we want to support what's 
> supported officially to not exclude others. That's why we started this thing.
> I'd really welcome the bi-yearly LTS release cycle with one year of LTS 
> support overlap - the longer the better.
> 
> Philippe
> 
> Am Mittwoch, 3. Juni 2015 15:25:21 UTC+2 schrieb Tim Graham:
> When do you drop support for old versions of Django? The main concern I have 
> is that it somewhat encourages running on unsupported and insecure versions 
> of Django (currently 1.5, 1.6; and 1.4 will be end of life in October). 
> Therefore I don't thinking giving it an official blessing is a good idea.
> 
> In the "1.9 release planning" thread I proposed a new deprecation schedule to 
> make it easier for third-party apps to support the currently supported Django 
> versions now that we have LTS releases. Here's that proposal:
> 
> https://docs.google.com/document/d/1bC6A8qc4skCmlagOnp8U7ddgyC-1XxXCBTlgrW690i0/edit?usp=sharing
> 
> Feedback on that will would be welcome.
> 
> On Wednesday, June 3, 2015 at 6:14:39 AM UTC-4, Philippe O. Wagner wrote:
> TLDR; Introducing django-compat - arteria's solution for for- and backwards 
> compatibility from Django 1.4.x to 1.8.x./1.9.x
> 
> 
> SITUATION
> 
> We really love how Django evolves and how the core gets better and better. 
> New major versions of the framework that comes with changes, bugfixes and new 
> features are released quickly. This is great and nothing is wrong with that!
> 
> But there are issues from the business/agency/our point of view:
> 
> * We are not as fast as Django is
> * We have reusable apps that must work with multiple Django versions and
> * We have a lot of these apps, open and closed source
> 
> A lot of (3rd party/open source) apps
>  
> * ignore older Django version due to the additional effort or
> * have this try/except pattern everywhere in the code or
> * encapsulate them in a per app compat.py file, see a some example in the 
> projects README
> 
> All our "reusable apps" for client project and products where built on and 
> for the Django LTS 1.4 version. With the release of the new LTS version we 
> started every new project on 1.8, but still have all other older projects 
> that runs on 1.4 and depends on these apps and it's update 

Re: Composite fields

2015-03-04 Thread Loïc Bistuer
Hi Thomas,
 
fields/related.py is begging for a refactor of the existing relational fields, 
and ideally we'd build composite fields on top of this refactor.
 
The ORM has seen huge changes in the recent past: migrations, expressions, 
lookups, and last but not least a *public* footprint in Model._meta, each 
having both positive and negative (mostly backwards compatibility concerns) 
implications when it comes to redesigning relations. All of these didn't exist 
at the time of the previous two SoC attempts.

Taking a step back and looking at the problem from this new perspective takes 
time, and in the last couple of months both Anssi and I have been experimenting 
with a few ideas. Anssi has dedicated a lot of time to it in the last few 
weeks, let's wait for his feedback. Best case scenario, his design and 
implementation work and we don't have a SoC project anymore; if he can't follow 
through maybe he'll be interested in mentoring yet another SoC on this issue.

-- 
Loïc

> On Mar 5, 2015, at 09:58, Thomas Stephenson  wrote:
> 
> Hey there, 
> 
> Yeah, I've looked through some (probably not all) of the previous proposals 
> to support composite fields. I was going to wait until some more work had 
> been done to split concrete fields from virtual fields (ticket 16508), 
> because I thought that would be an ORM change that would have drastically 
> simplified things, but in the end I've found that I was able to keep the 
> implementation contained without it.
> 
> Sorry if I sounded impatient -- it was just a bit of humour to kickstart the 
> conversation, since my previous thread (about a couple of small changes to 
> the field API I'd like to make to support this proposal) had been languishing 
> for four days without a single response.
> 
> Thomas
> 
> On 5 March 2015 at 11:52, Curtis Maloney  wrote:
> Have you reviewed all the existing works on trying to add composite fields?
> 
> I know several managed to reach a level of maturity that was almost merge 
> quality, and am sure I heard some of the recent ORM changes would ease 
> support.
> 
> On 5 March 2015 at 11:42, Thomas Stephenson  wrote:
> OK, no need for everyone to shout -- your message is heard loud and
> clear. I'll go and find something else to work on.
> 
> 
> Wow... impatient much?  Not everyone works in your timezone, or to your 
> schedule.  I, for one, was planning to take some time to review your proposal 
> carefully, instead of "first thing in the morning whilst still having my 
> coffee", as I feel it's a topic that deserves careful consideration.
> 
> Don't you think it's worth giving everyone a chance to read your email before 
> you give up and move on?  It's only been 11 hours.  Many of us were asleep 
> for most of that.
> 
> --
> Curtis
> 
>  
> On 5 March 2015 at 00:16, Thomas Stephenson  wrote:
> > Considering the past two proposals I've made here, I doubt I'll get more
> > than an echo chamber effect on this one.
> >
> > For the past week or so I've spent a bit of time on a feature I've always
> > wanted to see land in django -- composite fields. The tickets have been open
> > in the bug tracker for quite some time (and there's a few related ones, such
> > as multi-column primary keys that can all be killed with the one stone).
> >
> > The work is available on this branch of my fork of django for the moment --
> > I haven't opened up a PR yet because there's still some features that are
> > still to be implemented that will be explained below, but I want to give
> > everybody a chance to tell me where I can stick it before I spend *too* much
> > time on it.
> >
> > So, without further ado, the proposal.
> >
> >
> > Composite Fields - Implemented
> >
> > A composite field is an encapsulation of the functionality of a subset of
> > fields on a model. Composite fields can be defined in one of two ways:
> >
> > 1. Statically declared composite fields
> >
> > A statically declared composite field is defined in the same way a django
> > model is defined. There are two customisable transformation functions,
> > CompositeField.value_to_dict(self, value) and
> > CompositeField.value_from_dict(self, value) which can be used to associate
> > the field with a python object.
> >
> > All the serialization functions are implemented via the implementations of
> > the subfields.
> >
> > For example,
> >
> > class MoneyField(models.CompositeField):
> >currency_code = models.CharacterField(max_length=3)
> >amount = models.DecimalField(max_digits=16, decimal_digits=4)
> >
> >## Overriding __init__ can be used to pass field parameters to the
> > subfields
> >
> >def value_from_dict(self, value):
> >if value is None:
> >   return None
> >return Money(**value)
> >
> >def value_to_dict(self, value):
> >   if value is None:
> >  return None
> >   return {attr: getattr(value, attr) for attr in 

Re: django admin: open popups as modals instead of windows

2015-02-24 Thread Loïc Bistuer
> 
> On Feb 25, 2015, at 09:07, Russell Keith-Magee  
> wrote:
> 
> I have an operating system with a graphical user interface. The developers of 
> that operating system spent an immense amount of time developing it, 
> polishing it, making it behave in predictable ways, getting keyboard 
> accessibility sorted out, and so on. The idea of a CSS+HTML+JS implementation 
> of UI features that badly implement half of the behavior provided natively by 
> the OS - and the idea that this implementation is somehow *preferable* to 
> native UI elements - absolutely *boggles* my mind. 

While I agree on desktop OS, I find responsive HTML modals much more usable on 
mobile.

That said, HTML modals vs popups is hardly the biggest issue we have when it 
comes to usability on mobile platforms, which isn't surprising considering the 
admin look & feel was invented way before mobile was a thing.

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/82A2D68B-C6BA-4DCB-B73E-494C4DF5955F%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: status of 1.8 release blockers

2015-02-18 Thread Loïc Bistuer
>From my point of view #24351 is ready for a final sanity check and merging.

-- 
Loïc

> On Feb 19, 2015, at 10:10, Tim Graham  wrote:
> 
> 3 issues remain. I haven't confirmed with the owners, but it seems to me 
> there may be a good chance to wrap them up tomorrow.
> 
> 
> #24351  RunPython/RunSQL operations in contrib migrations and 
> multi-db routers.
> Owner: Loic
> Status: In review.
> 
> 
> #24328 The new Options._get_fields() method needs to be cleaned up
> Owner: Anssi
> Status: In review.
> 
> #24343 UUID foreign key accessor returns inconsistent type
> 
> Owner: Marc
> Status: Marc to polish patch.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/170625d3-1bb5-4b9d-ab74-501fd5dea86b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/136699C8-42D8-47E9-B0A6-78C8E7BA96A3%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Signature of the allow_migrate database router.

2015-02-18 Thread Loïc Bistuer
Individual routers don't have a base class but we can add it to the master 
router `django.db.router`. I've updated the PR with a 
`router.allow_migrate_model` method. I don't know if we should document this 
just yet.

Internally we now treat anything other than `app_label` as a hint, but I guess 
we should still document `model_name=None` as part of the official signature.

Speaking about `model_name`, it seems to be the lowercase version of 
`_meta.object_name` (which is basically __name__). I didn't investigate 
further, can you confirm that `_meta.model_name` is what we want?

> On Feb 18, 2015, at 15:41, Aymeric Augustin 
> <aymeric.augus...@polytechnique.org> wrote:
> 
> 2015-02-18 6:34 GMT+01:00 Loïc Bistuer <loic.bist...@gmail.com>:
> Another option would be to make the signature `allow_migrate(self, db, 
> app_label, model_name=None, **hints)` and to put the model class in the hints 
> dict, the same way we pass `instance` as hint to the other routers.
> 
> Yes, that's what I wanted to suggest after Andrew confirmed my suspicion that 
> we have to account for historical models.
> 
> Perhaps the following convenience function can help factoring out the 
> arguments in the common case:
> 
> def allow_migrate_model(router, db, model):
> return router.allow_migrate(db, model._meta.app_label, 
> model._meta.model_name, model=model)
> 
> (This isn't a router method because there isn't a base class for routers.)
> 
> -- 
> Aymeric.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/CANE-7mVJpobigSdmEQt1NdkXOyjDWdPoEZJz4TVdVDeG9g%2BS2w%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/A38EDB7A-9099-49A1-B4EA-86BBF393B792%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Signature of the allow_migrate database router.

2015-02-17 Thread Loïc Bistuer
Another option would be to make the signature `allow_migrate(self, db, 
app_label, model_name=None, **hints)` and to put the model class in the hints 
dict, the same way we pass `instance` as hint to the other routers.

That would make the 80% use-case less fiddly without any loss of functionality.

-- 
Loïc

> On Feb 18, 2015, at 11:45, Loïc Bistuer <loic.bist...@gmail.com> wrote:
> 
> 
>> On Feb 18, 2015, at 05:18, Andrew Godwin <and...@aeracode.org> wrote:
>> 
>> I am fine with the proposed change to allow better routing of 
>> RunSQL/RunPython (though in the RunPython case people can easily do routing 
>> inside the python code provided anyway, as you can see the DB aliases there).
> 
> True although that tightly couples the host migration and the routing step. 
> It is fine if you control both but you are out of luck if the migration is in 
> a reusable or third-party app.
> 
>> On Tue, Feb 17, 2015 at 12:58 PM, Aymeric Augustin 
>> <aymeric.augus...@polytechnique.org> wrote:
>> 
>> Did you consider the following signature?
>> def allow_migrate(self, db, app_label, model_name=None, **hints):
>> While it’s a slightly larger change, it has a several advantages:
>> - passing (app_label, model_name) as strings is an established convention in 
>> many other APIs.
>> - it removes the possibility that app_label != model._meta.app_label — which 
>> doesn’t make much sense anyway.
>> - our examples only ever use app_label — and keep repeating 
>> model._meta.app_label to get it.
>> 
>> If the model class is needed, it can be fetched with 
>> apps.get_model(app_label, model_name).
> 
> It's a fair proposal but it's hard to predict what people currently do with 
> their routers. I've only ever needed to "identify" models, so it would 
> suffice for my needs.
> 
> The only (slightly convoluted) use-case I can think of is pushing the routing 
> decision onto a model or manager method. For model methods you'd have to be a 
> bit crafty by using non-model base classes, and for manager methods you'd 
> have to use Django 1.8 since custom managers weren't supported before. In 
> both cases versioning is bypassed and there is the requirement that classes 
> still exist in the codebase, but at least it's not coupled to the existence 
> of a specific model like `apps.get_model(app_label, model_name)` would.
> 
> It's a tangent but seeing this, we should definitely turn the `model` (or 
> `model_name`) arg into kwarg even if only in the docs, that'll make it more 
> obvious that it's not always there.
> 
>> PS: we chose to make 1.8 the next LTS instead of 1.7 precisely so we could 
>> make such adjustments.
> 
> +1
> 
> -- 
> Loïc
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0749ADD0-3402-4131-A4BF-AC4BC12DB6B0%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Signature of the allow_migrate database router.

2015-02-17 Thread Loïc Bistuer

> On Feb 18, 2015, at 05:18, Andrew Godwin  wrote:
> 
> I am fine with the proposed change to allow better routing of 
> RunSQL/RunPython (though in the RunPython case people can easily do routing 
> inside the python code provided anyway, as you can see the DB aliases there).

True although that tightly couples the host migration and the routing step. It 
is fine if you control both but you are out of luck if the migration is in a 
reusable or third-party app.

> On Tue, Feb 17, 2015 at 12:58 PM, Aymeric Augustin 
>  wrote:
> 
> Did you consider the following signature?
> def allow_migrate(self, db, app_label, model_name=None, **hints):
> While it’s a slightly larger change, it has a several advantages:
> - passing (app_label, model_name) as strings is an established convention in 
> many other APIs.
> - it removes the possibility that app_label != model._meta.app_label — which 
> doesn’t make much sense anyway.
> - our examples only ever use app_label — and keep repeating 
> model._meta.app_label to get it.
> 
> If the model class is needed, it can be fetched with 
> apps.get_model(app_label, model_name).

It's a fair proposal but it's hard to predict what people currently do with 
their routers. I've only ever needed to "identify" models, so it would suffice 
for my needs.

The only (slightly convoluted) use-case I can think of is pushing the routing 
decision onto a model or manager method. For model methods you'd have to be a 
bit crafty by using non-model base classes, and for manager methods you'd have 
to use Django 1.8 since custom managers weren't supported before. In both cases 
versioning is bypassed and there is the requirement that classes still exist in 
the codebase, but at least it's not coupled to the existence of a specific 
model like `apps.get_model(app_label, model_name)` would.

It's a tangent but seeing this, we should definitely turn the `model` (or 
`model_name`) arg into kwarg even if only in the docs, that'll make it more 
obvious that it's not always there.

> PS: we chose to make 1.8 the next LTS instead of 1.7 precisely so we could 
> make such adjustments.

+1

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/E5E8EEBA-CA5B-43CF-8D0E-B044CE20B5D8%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Signature of the allow_migrate database router.

2015-02-17 Thread Loïc Bistuer
Hi Tim,

The API doesn't assume anything, it just gives to the router all the 
information that's available, which is limited to connection_alias and 
app_label in the case of RunPython/RunSQL.

Previously all RunPython/RunSQL operations would run on every db no matter 
what, this is obviously broken for many multi-db setups.

With this branch at the very least you'd get the app_label which is sufficient 
for routing in most cases.

If you need even more granularity then you need the operations to give you some 
hints. For example a RunPython operation could provide the list of affected 
models with `hints={'affected_models': [ModelA, ModelB]}`, but when you need 
this level of control over routing, you hopefully also control the app so you 
can easily provide the hints that you need.

-- 
Loïc

On Feb 18, 2015, at 00:16, Tim Graham <timogra...@gmail.com> wrote:
> 
> I'm not a big user of multi-db so I could be wrong here, but it seems like 
> this API seems to assume that all models in a given app are stored in the 
> same database. Have you thought through what happens if this isn't true? This 
> question seems to come into play when we allowed model=None in RunPython/SQL.
> 
> On Tuesday, February 17, 2015 at 5:06:24 AM UTC-5, Loïc Bistuer wrote:
> Hi all, 
> 
> The proposed fix for the release blocker 
> https://code.djangoproject.com/ticket/24351 suggests changing the signature 
> of the `allow_migrate` database router. 
> 
> From: 
> def allow_migrate(self, db, model): 
> 
> To: 
> def allow_migrate(self, db, app_label, model, **hints): 
> 
> We need to make a design decision. 
> 
> Some background: 
> 
> 1. Django 1.7 doesn't call the `allow_migrate` router for RunPython and 
> RunSQL operations. If you control all migrations you can somewhat work around 
> the issue inside RunPython using 
> https://github.com/django/django/blob/1.7.4/docs/topics/migrations.txt#L472-L500,
>  but you still have to stay away from RunSQL, and you are out of luck if 
> these operations live in django.contrib or in a third-party app. 
> 
> 2. Behavior from 1. changed in Django 1.8 (#22583) and the RunPython and 
> RunSQL operations now call `allow_migrate` with `model=None`. These 
> operations also accept a `hints` kwarg that is passed as `**hints` to 
> `allow_migrate`. Unless hints are provided `allow_migrate` can only make a 
> blanket yes/no decision because it doesn't have anything other than the 
> `db_alias` to work with. 
>  
> 3. The change from 2. is backwards incompatible in a sense that routers will 
> blow up if they don't expect None as a possible value for `model`. The 
> `hints` part is backwards compatible as long as no migrations make use of 
> them. 
> 
> 4. Django 1.8 introduced a migration for contrib.contenttypes that contains a 
> RunPython operation 
> (https://github.com/django/django/blob/b4ac23290772e0c11379eb2dfb81c750b7052b66/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py#L33-L36).
>  This is a problem because it won't work in many multi-db setups. The problem 
> already existed for third-party apps but now it becomes a core issue. 
> 
> 5. We could take advantage of 2. to fix 4. (e.g. `RunPython(noop, 
> add_legacy_name, hints={'app_label': 'contenttypes'})`) which would allow 
> multi-db users to make a routing decision, but then we introduce a backwards 
> incompatibility (see point 3.) that requires changing the signature of 
> `allow_migrate` in user code (to expect either the `app_label` kwarg or 
> `**hints`). While this would fix the problem for contrib.contenttypes, the 
> problem would still exist in third-party apps unless they also cooperate by 
> providing similar hints (note that those that still want to support 1.7 
> projects won't be able to do so). 
> 
> 6. `app_label` applies to all operations including RunPython and RunSQL, 
> `model` only applies to some model operations (CreateModel, AddField, etc.). 
> Our docs and tests only use the `model` argument to dig out the `app_label`, 
> and I suspect this is the most common usage (at least it certainly matches my 
> usage). 
> 
> My opinion is that `app_label` is always useful in `allow_migrate`, even if 
> only as a first pass before inspecting the model, so since we are introducing 
> a change in the signature of `allow_migrate`, we might as well bite the 
> bullet and make it a required argument. The latest version of my branch 
> https://github.com/django/django/pull/4152 does this while still supporting 
> the old signature during a deprecation period. 
> 
> An alternative that was proposed by Markus is to pass `app_label` as a hint 
> instead of arg from within `allowed_to_migrate`. I don't think it's a good 
> idea because it's just as invasive (the signat

Signature of the allow_migrate database router.

2015-02-17 Thread Loïc Bistuer
Hi all,

The proposed fix for the release blocker 
https://code.djangoproject.com/ticket/24351 suggests changing the signature of 
the `allow_migrate` database router.

From:
def allow_migrate(self, db, model):

To:
def allow_migrate(self, db, app_label, model, **hints):

We need to make a design decision.

Some background:

1. Django 1.7 doesn't call the `allow_migrate` router for RunPython and RunSQL 
operations. If you control all migrations you can somewhat work around the 
issue inside RunPython using 
https://github.com/django/django/blob/1.7.4/docs/topics/migrations.txt#L472-L500,
 but you still have to stay away from RunSQL, and you are out of luck if these 
operations live in django.contrib or in a third-party app.

2. Behavior from 1. changed in Django 1.8 (#22583) and the RunPython and RunSQL 
operations now call `allow_migrate` with `model=None`. These operations also 
accept a `hints` kwarg that is passed as `**hints` to `allow_migrate`. Unless 
hints are provided `allow_migrate` can only make a blanket yes/no decision 
because it doesn't have anything other than the `db_alias` to work with.

3. The change from 2. is backwards incompatible in a sense that routers will 
blow up if they don't expect None as a possible value for `model`. The `hints` 
part is backwards compatible as long as no migrations make use of them.

4. Django 1.8 introduced a migration for contrib.contenttypes that contains a 
RunPython operation 
(https://github.com/django/django/blob/b4ac23290772e0c11379eb2dfb81c750b7052b66/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py#L33-L36).
 This is a problem because it won't work in many multi-db setups. The problem 
already existed for third-party apps but now it becomes a core issue.

5. We could take advantage of 2. to fix 4. (e.g. `RunPython(noop, 
add_legacy_name, hints={'app_label': 'contenttypes'})`) which would allow 
multi-db users to make a routing decision, but then we introduce a backwards 
incompatibility (see point 3.) that requires changing the signature of 
`allow_migrate` in user code (to expect either the `app_label` kwarg or 
`**hints`). While this would fix the problem for contrib.contenttypes, the 
problem would still exist in third-party apps unless they also cooperate by 
providing similar hints (note that those that still want to support 1.7 
projects won't be able to do so).

6. `app_label` applies to all operations including RunPython and RunSQL, 
`model` only applies to some model operations (CreateModel, AddField, etc.). 
Our docs and tests only use the `model` argument to dig out the `app_label`, 
and I suspect this is the most common usage (at least it certainly matches my 
usage).

My opinion is that `app_label` is always useful in `allow_migrate`, even if 
only as a first pass before inspecting the model, so since we are introducing a 
change in the signature of `allow_migrate`, we might as well bite the bullet 
and make it a required argument. The latest version of my branch 
https://github.com/django/django/pull/4152 does this while still supporting the 
old signature during a deprecation period.

An alternative that was proposed by Markus is to pass `app_label` as a hint 
instead of arg from within `allowed_to_migrate`. I don't think it's a good idea 
because it's just as invasive (the signature of existing routers still need to 
change) and we make it less obvious to people calling `router.allow_migrate()` 
directly that they should supply an `app_label`. It's IMO more error prone if 
we can't reliably expect that `app_label` will be provided because it requires 
writing additional defensive code.

Thoughts?

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/4384E3A1-9454-4A34-9583-892430D89A60%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Feature proposal: Allow shadowing of abstract fields

2015-02-16 Thread Loïc Bistuer
Hi Marten,

As mentioned in my previous email I don't recommend an implementation based on 
locks.

Please look at how Form and ModelForm support inheritance and shadowing without 
it.

-- 
Loïc

> On Feb 16, 2015, at 21:35, Marten Kenbeek <marten.k...@gmail.com> wrote:
> 
> Okay, as things were getting more and more complicated I sat down for a while 
> to get back to the essence of this patch. The result [1] is much, much 
> cleaner and works perfectly. I'll start working on documentation as well.
> 
> [1] https://github.com/knbk/django/tree/ticket_24305_alternative
> 
> Op vrijdag 13 februari 2015 15:28:53 UTC+1 schreef Marten Kenbeek:
> Hi Loïc,
> 
> Thanks for the response. I will change my code to generate errors in the case 
> of abstract fields shadowing concrete fields. 
> 
> At the moment, the locking mechanism of fields is pretty much the core of 
> this patch. It is explicitly set to `True` when fields are added to a 
> concrete model, and it allows to easily check if a field can be changed. 
> Without it, a proper, clean way would be needed to check the origin of the 
> field. If for example an abstract model inheriting from a concrete model adds 
> some fields, you should be able to shadow the new fields, but not the 
> inherited fields. Making it internal would be clunky with the way cloning and 
> serializing currently works.
> 
> I'm not too content with this anyway. As the default has to be `False` (for 
> an opt-in behaviour for abstract fields, rather than an opt-out behaviour), 
> this unnecessarily clutters migrations and other serialized values with 
> `locked=True` for concrete classes. However, it's not trivial to consistently 
> determine if a field is in any way inherited from a concrete class. I will 
> look into a clean method to determine this.
> 
> I don't think we should remove it entirely, unless we provide another 
> mechanism to prevent field changes for some abstract fields. E.g. 
> django-polymorphic completely depends on the `polymorphic_ctype` field. That 
> might be a rare name to use, but it shows that some code does depends on 
> abstract fields. With the locking mechanism, we move the responsibility of 
> ensuring the right behaviour of that field to the package developer rather 
> than the website developer. I think a fail hard, fail fast approach is better 
> for these situations than going along with the possibility of subtle or 
> not-so-subtle bugs. 
> 
> Op donderdag 12 februari 2015 17:59:58 UTC+1 schreef Loïc Bistuer:
> Hi Marten, 
> 
> Sorry for the late response, it's been a busy week. Thanks for working on 
> this, I'll try to have a look at your branch this weekend. 
> 
> In the meantime I'll leave some comments below. 
> 
> > On Feb 12, 2015, at 22:43, Marten Kenbeek <marte...@gmail.com> wrote: 
> > 
> > Current status: 
> > • Models in general seem to be working. 
> > • Trying to override a concrete (or explicitly locked) field with 
> > an abstract field will keep the concrete field, but not raise any errors. 
> > This occurs when inheriting from (AbstractBase, ConcreteBase). 
> > • I might still change this to raise an error, it migth 
> > cause a few headaches when fields don't appear while they're first in the 
> > mro. 
> 
> This should definitely be an error. We recently added checks so two concrete 
> parents can't have clashing fields, this is similar. 
> 
> > • Trying to override field.attname (e.g. foo_id) will fail checks 
> > unless you explicitly set foo = None. 
> > • Trying to override an abstract field with a reverse relation will 
> > fail checks unless you explicitly set foo = None. 
> 
> That's good. 
> 
> > What is still needed: 
> > • ? More extensive model tests. During development a few more bugs 
> > popped up. I've written tests for them, but there might be some more. 
> > • Explicit migration tests. Existing migration tests pass, but 
> > don't include the new scenario's. 
> > • Documentation. 
> > My WIP branch can be found at 
> > https://github.com/knbk/django/compare/ticket_24305. 
> > 
> 
> > Op dinsdag 10 februari 2015 14:36:53 UTC+1 schreef Marten Kenbeek: 
> > Hi Aron, 
> > 
> > With option 3, this would work: 
> > 
> > class Cousin(models.Model): 
> > child = models.ForeignKey(Child, allow_override=True) 
> > 
> > but it would raise an error without `allow_override`. 
> > 
> > I think my question really is: should we treat reverse relations as 
> > first-class fields, or not? If we do, 1) would be the logical choice but 
> > can cause problems. 

Re: Feature proposal: Allow shadowing of abstract fields

2015-02-12 Thread Loïc Bistuer
; that prevents you from accidentally overriding fields. 2) would only allow 
> the inheriting model itself to change which fields it inherits. 
> 
> Problems caused by option 1) would be hard to debug when you don't know which 
> code overrides your field, so I wouldn't do that. I think 2) would be the 
> cleanest and most consistent way. Only local fields would override parent 
> fields, but the sentinel value `None` would remove the field and free the 
> name for reverse relations. I can also see the advantage of 3) over 2) when 
> you don't have access to the model on the other side. However, I don't know 
> enough about foreign key internals to know if 3) is at all feasible. What 
> happens e.g. when only the target is loaded in a migration? Would it pick up 
> that the remote foreign key overrides a local field? As adding reverse 
> relations is a lazy, or at least delayed operation afaik, would it still be 
> save to rely on that to override fields?
> 
> I believe my current plans for the patch would automatically create situation 
> 2 without any extra work. The field would no longer exist on the child class 
> when the reverse relation is added. Option 3) would require an additional 
> patch to the code that adds the reverse relationship, but it allows for some 
> extra options.
> 
> Any input? Additional options are also welcome. 
> 
> Op zondag 8 februari 2015 21:09:41 UTC+1 schreef Marten Kenbeek:
> The general reaction seems to be a yes if we can work out the kinks, so I 
> went ahead and created a ticket: https://code.djangoproject.com/ticket/24305
> 
> @Aron That's a good question. One option would be to lock certain fields, so 
> that they can't be changed if they are an integral part of the model. That 
> would be a simple solution, but that won't help for existing code that 
> doesn't lock the fields. It won't break existing code, but it won't protect 
> for errors either. The opt-in version (i.e. an 'unlock' attribute) would lock 
> many fields which would otherwise be completely safe to overwrite. 
> 
> Another option would be more elaborate "requirements" for a manager or some 
> methods, i.e. allow the manager to specify the necessary class of a certain 
> field or a minimum length. If the modeldoesn't meet the requirements, the 
> manager or some of the methods will not be inherited. While it allows for 
> more control, this option would greatly increase the complexity of the patch 
> and requires more from the developers of custom managers. It can also cause 
> issues when the requirements aren't up-to-date with the manager's methods. 
> 
> We could also say that it is the users responsibility and don't provide 
> special protection, in line with the fields themselves, but I guess that this 
> would generally be more problematic for custom managers. It can also cause 
> silent bugs when the manager's methods don't work as intended but won't raise 
> an exception either, which is not a good idea imho. 
> 
> I think the locking approach would be the easiest and most pragmatic method. 
> I think it's still - in part - the users responsibility to confirm that a 
> field can be overridden. The Django documentation could, where applicable, 
> document the requirements on fields that can be overridden, i.e. that an 
> AbstractUser's username must be a CharField (which isn't necessarily true, 
> just an example). 
> 
> @Loïc The bases are indeed traversed in the reversed order. 
> 
> Op zondag 8 februari 2015 08:19:57 UTC+1 schreef Loïc Bistuer:
> That's what we've done in Django 1.7 for Form/ModelForm (#19617, #8620), and 
> I completely agree that it should be possible to shadow fields from abstract 
> models. The docs even suggest that this may be possible in the future; 
> quoting the relevant section: "this [shadowing] is not permitted for 
> attributes that are Field instances (at least, not at the moment)." 
> 
> For consistency with forms - and because we've put a great deal of thinking 
> into it - the implementation should be: you can shadow a field with another 
> field, or you can remove a field using None as a sentinel value (see #22510 
> for more details). 
> 
> I believe we have a safety net in the form of migrations, if you accidentally 
> shadow a field, migrations will pick it up, so it's unlikely to go unnoticed. 
> 
> I'd be quite happy to shepherd this patch. 
> 
> Unit tests should cover those scenarios: 
> 
> - An abstract model redefines or removes some fields from a parent abstract 
> model. 
> - A concrete model redefines or removes some fields from a parent abstract 
> model. 
> - Ensure that the standard MRO resolution applies when you do 
> Concrete(AbstractA, AbstractB) with AbstractA redef

Re: Feature proposal: Allow shadowing of abstract fields

2015-02-07 Thread Loïc Bistuer
That's what we've done in Django 1.7 for Form/ModelForm (#19617, #8620), and I 
completely agree that it should be possible to shadow fields from abstract 
models. The docs even suggest that this may be possible in the future; quoting 
the relevant section: "this [shadowing] is not permitted for attributes that 
are Field instances (at least, not at the moment)."

For consistency with forms - and because we've put a great deal of thinking 
into it - the implementation should be: you can shadow a field with another 
field, or you can remove a field using None as a sentinel value (see #22510 for 
more details).

I believe we have a safety net in the form of migrations, if you accidentally 
shadow a field, migrations will pick it up, so it's unlikely to go unnoticed.

I'd be quite happy to shepherd this patch.

Unit tests should cover those scenarios:

- An abstract model redefines or removes some fields from a parent abstract 
model.
- A concrete model redefines or removes some fields from a parent abstract 
model.
- Ensure that the standard MRO resolution applies when you do 
Concrete(AbstractA, AbstractB) with AbstractA redefining a field from AbstractB.

The last case may be tricky because if I remember well ModelBase iterates 
through the MRO in the wrong direction (i.e. bases should be iterated over in 
reverse).

We also need some tests to show how migrations behave.

-- 
Loïc

> On Feb 7, 2015, at 09:33, Marten Kenbeek  wrote:
> 
> Hi Russ,
> 
> I can see your point on accidentally overriding fields, though I'm not sure I 
> agree. In any other case, such as normal attributes and methods, there is no 
> safety net for overriding attributes either. Any model that would be affected 
> by this change would also raise an error on import without the patch, so 
> existing functional code won't be affected. On the other hand, a new 
> parameter for the field wouldn't be that much of a hassle to implement or 
> work with. I'd be interested to hear what others think about this.
> 
> There are more than a few questions on stack overflow that expect this 
> behaviour, even if the docs specifically mention that it won't work. If users 
> intuitively try to override fields in this manner, I think it would be 
> reasonable to allow this without any explicit arguments.
> 
> We can always restrict what you can override, at least as the default 
> behaviour, e.g. so that you can only use subclasses of the original field. 
> That would make code that depends on the abstract field less prone to bugs, 
> though subtle bugs can still happen if you e.g. override the max length of a 
> field. 
> 
> This was indeed just a proof-of-concept. That remark was meant more like "it 
> doesn't appear to break everything". 
> 
> Marten
> 
> Op vrijdag 6 februari 2015 23:48:55 UTC+1 schreef Marten Kenbeek:
> Hey,
> 
> While fiddling with django I noticed it would be trivial to add support for 
> shadowing fields from abstract base models. As abstract fields don't exist in 
> the database, you simply have to remove the check that reports name clashes 
> for abstract models, and no longer override the field. 
> 
> This would allow you to both override fields from third-party abstract models 
> (e.g. change the username length of AbstractUser), and to override fields of 
> common abstract models on a per-model basis. Previously you'd have to copy 
> the original abstract model just to change a single field, or alter the field 
> after the model definition. The first approach violates the DRY principle, 
> the second approach can introduce subtle bugs if the field is somehow used 
> before you changed it (rare, but it can happen). 
> 
> This patch adds the feature. It seems to work correctly when using the models 
> and creating/applying migrations, and passes the complete test suite. 
> 
> What do you guys think about this feature?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/072149e1-c794-446d-957b-f5fc5df87096%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web 

Re: Usage of field cardinality flags in database schema backends

2015-02-02 Thread Loïc Bistuer
Thanks Markus for the detailed report.

On a conceptual level I think we should aim for:

- django.db.* only relies on get_internal_type().
- django.* only relies on field flags.

To address the immediate regressions I suggest we backport 
https://github.com/django/django/pull/4002/files as far back as 1.7. That would 
address #24236 without requiring 
https://github.com/django/django/pull/3998/files.

In master:

- Replace all isinstance(field.rel) by isinstance(field) as a first step, this 
will help normalize things for future refactors (i.e. composite / virtual 
fields refactor, refactor of *Rel into proper fields like ReverseForeignKey, 
etc.)

- Replace all isistance(field) by get_iternal_type() in the ORM.

- More tricky, replace all isinstance(field) in the rest of django by 
cardinality flag when possible and identify every place where we can't do it 
yet because we rely on the implementation of these fields.

-- 
Loïc

> On Jan 31, 2015, at 18:19, Markus Holtermann  wrote:
> 
> Hey all,
> 
> Since Django 1.8 (currently in alpha state), model fields gained cardinality 
> flags as part of the _meta refactoring. So, there is one_to_one, one_to_many, 
> many_to_one and many_to_many. These flags are currently only used inside 
> user-facing APIs such as forms and the admin.
> 
> Furthermore model fields have a get_internal_type() method that returns 
> self.__class__.__name__ if they don't explicitly override that function (as 
> many of the built-in fields do). This method is heavily used inside the 
> backends.
> 
> Besides those two ways to "try" to figure out what Django has to do in a 
> certain situation, the code uses e.g. isinstance(field.rel, ManyToManyRel) 
> and isinstance(field, ManyToManyField) to check for many-to-many 
> relationships.
> 
> This is quite confusing. At least to me. In 
> https://github.com/django/django/commit/38c17871bb6dafd489367f6fe8bc56199223adb8
>  I committed a patch that uses field.many_to_many in order to figure out if a 
> certain column needs to be copied from one table to another (it doesn't if 
> it's an m2m relation) when altering a table on SQLite.
> 
> However changing that to use get_internal_name() and keep existing code 
> working is not trivial since neither ForeignKey nor ManyToManyField or 
> OneToOneField have those methods defined. Thus fields inheriting from either 
> of them need to explicitly define the method to return "ForeignKey", 
> "ManyToManyField" or "OneToOneField". (The backport of that patch to 1.7 
> unfortunately breaks existing projects).
> 
> I have a pull request open to fix the issue on 1.7 related to m2m fields: 
> https://github.com/django/django/pull/3998 .
> 
> However, I don't really like that repetitive pattern of checking for 
> inheritance and get_internal_type(). I'm thinking about keeping the pattern 
> in 1.8 (and replacing the above checks with the one in the pull request) and 
> accept https://github.com/django/django/pull/4002 for 1.9. Thus all projects 
> and apps that rely on the class name of a related fields need to update their 
> code and explicitly return the class name.
> 
> Thoughts and input highly welcome.
> 
> /Markus
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/b66842ee-62d6-43f2-a3df-838020cf60a2%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/16A1F25D-DC93-4DC5-9CF1-6CD7C89642CB%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Settings: lists or tuples?

2015-01-19 Thread Loïc Bistuer


> On Jan 20, 2015, at 01:43, Andreas Kahnert  wrote:
> 
> Hi Loïc,
> 
> I agree that we should not discuss about the theoretical aspects too much 
> (while I disagree on your distinction, the API difference is just their 
> mutability, so unless you refer to python intern algorithms for sort- 
> /lookup- optimization (if so, excuse me) your distinction is just your 
> personal taste)

Presumably more than just my personal taste: 
https://docs.python.org/2/faq/design.html#why-are-there-separate-tuple-and-list-data-types.

-- 
Loïc

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/037D5ABF-C15F-4002-AF44-2954C57FE752%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Settings: lists or tuples?

2015-01-19 Thread Loïc Bistuer
Hi Andreas,

As Florian pointed out, you can't mutate a tuple, but you can mutate the 
settings object, so using a tuple or a frozendict won't buy you much.

Regarding the theoretical perspective, tuples aren't meant to be immutable 
lists. Tuples are for heterogenous collections of fixed size (e.g. GPS 
coordinates); whereas lists are for homogenous collections of variable size, 
which suits perfectly our settings use-case. Of course Python being Python you 
can use them however you like but let's not talk about theory in that case.

Cheers

-- 
Loïc


> On Jan 20, 2015, at 00:15, Andreas Kahnert  wrote:
> 
> Well, yep. You can't prevent programmers to do stupid things in python. But 
> I'm kind of a theroretician and it hurts me if I see that exactly that what 
> it should not be is proposed as the standard. And for the dicts: In my 
> private code-base I use a frozendict c-package I wrote.
> 
> @Collin: The notation used within settings.py isn't that important. But I 
> think in the moment the framework constructs the settings object all 
> sequences (might be generators as well) should be turned into tuples.
> 
> For the trailing-comma-problem: I notate every (globally available) constant 
> sequence in the pattern:
> A = (
> 1,
> 2,
> )
> which is perfectly PEP-conformant and makes reodering elements manually also 
> more easy because you can cut'n'paste whole lines.
> 
> Am Montag, 19. Januar 2015 17:35:44 UTC+1 schrieb Florian Apolloner:
> On Monday, January 19, 2015 at 3:45:18 PM UTC+1, Andreas Kahnert wrote:
> I'm not talking about modifications inside the settings.py but in other 
> place. With lists, unexperienced devs might do things like: from django.conf 
> import settings; settings.TEMPLATE_DIRS[3] = '/my_tpls'; and expect to work 
> out good.
> 
> And with tuples they just do settings.TEMPLATE_DIRS = 
> list(settings.TEMPLATE_DIRS) followed by your example. What I am trying to 
> say is that a developer ignoring the docs will always run into issues, no 
> matter how hard we try to prevent it. 
> 
> This is realy just a question of logic: lists are mutable - settings are 
> immutable; see the conflict?
> 
> Well, what is your suggestion for the dictionaries in the settings then ;) In 
> the end it just doesn't matter if it's a list or a tuple -- you can "mutate" 
> it anyways. For the functionality of Django it makes no difference if you 
> altered the setting in place or just replace it -- stuff __will__ break. 
> 
> Cheers,
> Florian
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/07fd597a-01d2-4f6c-845b-5587a19b3263%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5CF5D10A-9335-49A2-9CD4-7E0C7B81C8E6%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: delegating our static file serving

2014-12-05 Thread Loïc Bistuer
I'm +1 on this plan, "native" support for wsgi.file_wrapper makes a lot of 
sense.

-- 
Loïc

> On Dec 5, 2014, at 12:33 PM, Collin Anderson  wrote:
> 
> Hi All,
> 
> I'm pretty interested in getting secure and _somewhat_ efficient static file 
> serving in Django.
> 
> Quick history:
> 2005 - Jacob commits #428: a "static pages" view.  Note that this view should 
> only be used for testing!"
> 2010 - Jannis adds staticfiles. Serving via django is considered "grossly 
> inefficient and probably insecure".
> 2011 - Graham Dumpleton adds wsgi.file_wrapper to Gunicorn.
> 2012 - Aymeric adds StreamingHttpResponse and now files are read in chunks 
> rather than reading the entire file into memory. (No longer grossly 
> inefficient IMHO.)
> 
> I propose:
> - Deprecate the "show_indexes" parameter of static.serve() (unless people 
> actually use it).
> - Have people report security issues to secur...@djangoproject.com (like 
> always)
> - Audit the code and possibly add more security checks and tests.
> - add wsgi.file_wrapper support to responses (5-line proof of concept: 
> https://github.com/django/django/pull/3650 )
> - support serving static files in production, but still recommend 
> nginx/apache or a cdn for performance.
> - make serving static files in production an opt-in, but put the view in 
> project_template/project_name/urls.py
> 
> I think it's a huge win for low-traffic sites or sites in the "just trying to 
> deploy and get something live" phase. You can always optimize later by 
> serving via nginx or cdn.
> We already have the views, api, and logic around for finding and serving the 
> correct files.
> We can be just as efficient and secure as static/dj-static without needing to 
> make people install and configure wsgi middleware to the application.
> We could have staticfiles classes implement more complicated features like 
> giving cache recommendations, and serving pre-gzipped files.
> 
> Is this a good idea? I realize it's not totally thought through. I'm fine 
> with waiting until 1.9 if needed.
> 
> Collin
> 
> On Saturday, November 29, 2014 6:07:05 PM UTC-5, Collin Anderson wrote:
> Hi All,
> 
> I think doing something here is really good idea. I'm happy with any of the 
> solutions mentioned so far.
> 
> My question is: what does static/dj-static do that our built-in code doesn't 
> do? What makes it more secure? It seems to me we're only missing is 
> wsgi.file_wrapper and maybe a few more security checks. Why don't we just 
> make our own code secure and start supporting it?
> Here's basic wsgi.file_wrapper support: 
> https://github.com/django/django/pull/3650
> 
> We could then, over time, start supporting more extensions ourselves: ranges, 
> pre-gziped files, urls with never-changing content, etc. That way we get 
> very, very deep django integration. It seems to me this is a piece that a web 
> framework should be able to support itself.
> 
> Collin
> 
> 
> On Friday, November 28, 2014 9:15:03 AM UTC-5, Tim Graham wrote:
> Berker has worked on integrating gunicorn with runserver so that we might be 
> able to deprecate our own homegrown webserver. Windows support for gunicorn 
> is supposedly coming soon which may actually make the idea feasible. This way 
> we provide a more secure solution out of the box (anecdotes indicate that 
> runserver is widely used in production despite our documentation warnings 
> against doing so).
> 
> On the pull request, Anssi had an idea to use dj-static to serve static/media 
> files. My understanding is that we would basically integrate the code for 
> dj-static into Django and then add a dependency on static. It could be an 
> optional dependency since you might want to serve static files differently in 
> production, but it would likely be more or less universally used in 
> development. We could then say that django.views.static.serve (and its 
> counterpart in staticfiles) is okay to use in production (and I guess people 
> are already using them in production despite our warnings that they are not 
> hardened for production use).
> 
> What do you think of this plan?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers (Contributions to Django itself)" 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/bfc1eb0d-8b69-4450-bfe0-7147ef729317%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an