Re: A proposal for a new auto-reloader in Django

2017-03-30 Thread qingnian213
Hi Brice,
  Thanks for the suggestion! I'm not sure whether if I can successfully 
implement a library like you've mentioned, so for now I might stick with 
the Watch* libraries available. I really love the goals you've listed and 
would add these to my proposal.

David Ma

On Thursday, March 30, 2017 at 5:24:55 AM UTC-7, contact wrote:
>
> Hi David, 
> I think it's a good idea to improve what we have now, mostly for the 
> problems you described. 
> Don't you think it would be a better idea to make a reloader which 
> doesn't depend on Django at all? You could make a library working with a 
> settings file, and create a base settings file for Django projects. 
> You could define whatever should be called to start and restart the 
> server, and be able to define file types and folders that should be seen 
> as changes that require a restart or not. It could then be used easily 
> with any kind of Python project, and even allow specific behaviours, 
> like launching a server reload when a new plugin is uploaded to a 
> specific folder, or when one of them is updated. 
> Every Python framework could then embed their own base settings file, 
> which would allow this project to touch a wider audience. 
>
> - Brice 
>

-- 
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/f1194326-ed76-490f-999a-93cf6fc49890%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: A proposal for a new auto-reloader in Django

2017-03-30 Thread qingnian213
Hi Carl,
  Thanks for mentioning this awesome project! I saw it in one of the 
discussions but did not take a close look. I'll definitely check this out 
and try to integrate wsgiwatcher/watcher.py into Django.

On Thursday, March 30, 2017 at 7:47:13 AM UTC-7, Carl Meyer wrote:
>
> Anyone working on this project should at least be aware of 
> https://github.com/Pylons/hupper 
> 
>  
> (based on work David Glick and I 
> originally did in https://github.com/carljm/wsgiwatcher 
> ),
>  
> which aims to 
> be a framework-agnostic solution to this problem for any Python web 
> project. Docs at http://docs.pylonsproject.org/projects/hupper/en/latest/ 
>
> 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-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/59d28e31-49ea-41a3-b814-6025e155b256%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Adding signals to bulk update/create operations

2017-03-30 Thread Anssi Kääriäinen
The problem with passing the queryset is that it's possible that some 
object is added to or removed from the queryset between the pre_update and 
actual update execution. To avoid this the execution should go somewhere 
along the lines of:
   1) if there is pre_update or post_update do stages 2-5, if not, update 
as with current code
   2) fetch primary keys for models to be updated to a set, with 
.select_for_update() applied
   3) fire pre_update, give the primary key set as argument
   4) do the update against a queryset with .filter(pk__in=pk_set)
   5) fire post_update with primary key set as argument

This way the pre and post update signals will execute against a fixed set 
of instances. The bad part is that this can significantly slow down the 
.update() call, but to get actually safe signals, I don't see a way around 
that.

 - Anssi

On Friday, March 31, 2017 at 3:51:34 AM UTC+3, Tim Graham wrote:
>
> There's an accepted ticket about adding pre_update and post_update 
> signals: https://code.djangoproject.com/ticket/21461. From a quick 
> glance, I think this is what you're proposing.
>
> On Thursday, March 30, 2017 at 4:28:00 PM UTC-4, Todor Velichkov wrote:
>>
>> Consider the following piece of code:
>>
>> @receiver(pre_save, sender=MyModel)
>> def my_handler(sender, **kwargs):
>> instance = kwargs['instance']
>> if instance.verified:
>> do_something(instance)
>> else:
>> do_else(instance)
>>
>>
>>
>> Its good, because it keeps `MyModel` decoupled from `do_something`
>>
>> But there is one flaw. If we do:
>>
>> MyModel.objects.filter(verified=False).update(verified=True)
>>
>> we are screwed, `do_something` is not executed, and our models get 
>> out-of-sync.
>>
>> If we try to get smart and manually fire the pre_save signal for each 
>> instance, we are gonna have a hard time.
>> Its gonna be slow.
>> And its gonna be memory inefficient.
>>
>> We already experienced it in our app.
>>
>> So our new approach is like this:
>>
>> pre_bulk_update = Signal(providing_args=["queryset", "update_kwargs"
>> ])
>> post_bulk_update = Signal(providing_args=["update_kwargs",])
>>
>> pre_bulk_create = Signal(providing_args=["objs", "batch_size"])
>> post_bulk_create = Signal(providing_args=["objs", "batch_size"])
>>
>>
>> class MyModelQuerySet(models.QuerySet):
>> def update(self, **kwargs):
>> pre_bulk_update.send(sender=self.model, queryset=self, 
>> update_kwargs=kwargs)
>> res = super(MyModelQuerySet, self).update(**kwargs)
>> # The queryset will be altered after the update call
>> # so no reason to send it.
>> post_bulk_update.send(sender=self.model, update_kwargs=kwargs
>> )
>> return res
>>
>> def bulk_create(self, objs, batch_size=None):
>> pre_bulk_create.send(sender=self.model, objs=objs, batch_size
>> =batch_size)
>> res = super(MyModelQuerySet, self).bulk_create(objs, 
>> batch_size)
>> post_bulk_create.send(sender=self.model, objs=objs, 
>> batch_size=batch_size)
>> return res
>>
>>
>> class MyModel(models.Model):
>> #...
>> objects = MyModelQuerySet.as_manager()
>>
>>
>>
>> This gives us a nice interface to handle all kind of changes regarding 
>> `MyModel`
>> Our example usage looks like this:
>>
>>
>> @receiver(pre_save, sender=MyModel)
>> def my_handler(sender, **kwargs):
>> instance = kwargs['instance']
>> if instance.verified:
>> do_something(instance)
>> else:
>> do_else(instance)
>>
>>
>> @receiver(pre_bulk_update, sender=MyModel)
>> def my_bulk_update_handler(sender, **kwargs):
>> update_kwargs = kwargs['update_kwargs']
>> if 'verified' not in update_kwargs:
>> # no change im interested in
>> # no need to take any action
>> return
>>
>> queryset = kwargs['queryset']
>> pks_to_be_updated = queryset.values_list('pk', flat=True)
>> if update_kwargs['verified']:
>> do_something_bulk_update_implementation(pks_to_be_updated)
>> else:
>> bulk_update_do_else_implementation(pks_to_be_updated)
>>
>>
>> @receiver(pre_bulk_create, sender=MyModel)
>> def my_bulk_create_handler(sender, **kwargs):
>> objs = kwargs['objs']
>> group_1 = []
>> group_2 = []
>> for obj in objs:
>> if obj.verified:
>> group_1.append(obj)
>> else:
>> group_2.append(obj)
>>
>> if group_1:
>> do_something_bulk_create_implementation(group_1)
>> if group_2:
>> bulk_create_do_else_implementation(group_2)
>>
>>
>>
>> I think this turns out to be a very clean approach.
>> It help us use the most optimal strategy to handle the change.
>> So I'm sharing this with the community to check your feedback.
>> I believe if this gets into the Django Internals, it can be a very 
>> powerful tool.
>> It will lose power as a 3rd party app.
>>
>

-- 
You received this message 

Re: Add better support for ManyToMany with intermediary table fields, and reverse relationships, specially in forms

2017-03-30 Thread Collin Anderson
Hi Gabriel,

Yes, the hope is to make the situation better and more standard. Here's
some of the status:
https://code.djangoproject.com/ticket/24317 - real reverse fields.
https://code.djangoproject.com/ticket/897 - real reverse many to many fields
https://code.djangoproject.com/ticket/12203 - many to many with through
tables

Also, filtering fields on the .multiple attribute might help you out. Not
sure though. If it isn't, maybe open a pull request with a proposal for an
attribute that would work for you?

Quoting the advice from the first ticket:
- Find places where field.remote_field responds to different API than Field.
- Fix these one at a time while trying to have backwards compat, even if
the API isn't public.
- In addition, simplifications to the APIs are welcome, as is a high level
documentation of how related fields actually work.
- We need to try to keep backwards compat as many projects are forced to
use the private APIs.
- But most of all, do small incremental changes.

As far as your specific use-case goes, "a widget that is a table with
inputs for cells". The closest thing Django has is an "inline formset"
(though not actually a form field) which is designed exactly for reverse
relationships. You would say:

ThroughFormSet = inlineformset_factory(MainModel, ThroughModel)

https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#inline-formsets
(Or in the admin, you just use an inline which uses an inlineformset under
the hood.)

Collin


On Thu, Mar 30, 2017 at 3:30 PM, Gabriel Canto  wrote:

> When you are creating a system from scratch, coming with a ideal and
> organized model is simple enough, but when you are trying to replicate a
> real world system/issue into your models, things get complicated.
>
> By complicated I mean, almost every relationship is a M2M with
> intermediary fields, that's the issue I'm trying to solve using Django,
> real world documents, contracts, people.
>
> The main concern is making the CRUD web app easy for the user eyes.
>
> Django really made things difficult, specially because in our context the
> relationship direction doesn't matter, we want both forward and reverse
> fields when editing an object
>
>
> *First suggestion: give reverse relationships a common attribute for an
> easier way of getting them*
>
> This is the code I had to make to get only reverse relationships of a
> model, it is very ugly and not my proudest work, but it works(so far)
>
>  #I'm sure there's a better way of doing this
>  #This is the documented way of getting reverse fields, but it also gets
> ManyToOne rel with the through table of forward m2m rels, so we have to
> filter them
>  reverse_fields = [f for f in opts.get_fields() if f.auto_created and not
> f.concrete]
>  reverse_m2m = [f for f in reverse_fields if f.__class__.__name__ ==
> 'ManyToManyRel' and f.on_delete == None and not getattr(model,f.field.name
> ,False)]
>  #Also filtering the ManyToOne rel with the through table of the reverse
> m2m rels, because we need to differentiate them from reverse ManyToOne with
> other models(not through)
>  reverse_m2m_through = [f for f in reverse_fields if f.__class__.__name__
> == 'ManyToOneRel'  and f.related_model in [f.through for f in reverse_m2m
> if getattr(f,'through',False)]]
>  forward_m2m = [f.remote_field for f in opts.get_fields() if not 
> f.auto_created
> and f.many_to_many]
>  #Filtering the ManyToOne rels with the through table of forwards m2m
> rels, same logic as above
>  forward_m2m_through = [f for f in reverse_fields if f.__class__.__name__
> == 'ManyToOneRel'  and f.related_model in [f.through for f in forward_m2m
> if getattr(f,'through',False)]]
>  reverse_fields_final = itertools.chain(reverse_m2m, [f for f in
> reverse_fields if f not in itertools.chain(reverse_m2m,
> reverse_m2m_through, forward_m2m, forward_m2m_through)])
>
> *Second suggestion: following the first suggestion, give support to edit
> reverse rels in forms, and m2m with through tables*
>
> An optional argument to ModelForm to also catch reverse relationships,
> using a specific form field for it, example : ReverseModelChoiceField,
> etc..., this can be done with just a simple changes to their forward
> counterpart classes
>
> And, the most complex suggestion probably, is to add a form field to deal
> with M2M with through tables that contain intermediary fields, this can be
> done with a widget that is a table with inputs for cells, plus also work
> with reverse as suggested above, so I'm suggesting the creation of the 5
> following model form fields :
>
>
>1. ReverseModelChoiceField
>2. ReverseMultipleModelChoiceField
>3. ReverseManyToManyWithIntermediaryField (I'm sure there's a better
>name)
>4. ManyToManyWithIntermediaryField
>
> --
> 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 

Re: Adding signals to bulk update/create operations

2017-03-30 Thread Tim Graham
There's an accepted ticket about adding pre_update and post_update signals: 
https://code.djangoproject.com/ticket/21461. From a quick glance, I think 
this is what you're proposing.

On Thursday, March 30, 2017 at 4:28:00 PM UTC-4, Todor Velichkov wrote:
>
> Consider the following piece of code:
>
> @receiver(pre_save, sender=MyModel)
> def my_handler(sender, **kwargs):
> instance = kwargs['instance']
> if instance.verified:
> do_something(instance)
> else:
> do_else(instance)
>
>
>
> Its good, because it keeps `MyModel` decoupled from `do_something`
>
> But there is one flaw. If we do:
>
> MyModel.objects.filter(verified=False).update(verified=True)
>
> we are screwed, `do_something` is not executed, and our models get 
> out-of-sync.
>
> If we try to get smart and manually fire the pre_save signal for each 
> instance, we are gonna have a hard time.
> Its gonna be slow.
> And its gonna be memory inefficient.
>
> We already experienced it in our app.
>
> So our new approach is like this:
>
> pre_bulk_update = Signal(providing_args=["queryset", "update_kwargs"])
> post_bulk_update = Signal(providing_args=["update_kwargs",])
>
> pre_bulk_create = Signal(providing_args=["objs", "batch_size"])
> post_bulk_create = Signal(providing_args=["objs", "batch_size"])
>
>
> class MyModelQuerySet(models.QuerySet):
> def update(self, **kwargs):
> pre_bulk_update.send(sender=self.model, queryset=self, 
> update_kwargs=kwargs)
> res = super(MyModelQuerySet, self).update(**kwargs)
> # The queryset will be altered after the update call
> # so no reason to send it.
> post_bulk_update.send(sender=self.model, update_kwargs=kwargs)
> return res
>
> def bulk_create(self, objs, batch_size=None):
> pre_bulk_create.send(sender=self.model, objs=objs, batch_size=
> batch_size)
> res = super(MyModelQuerySet, self).bulk_create(objs, 
> batch_size)
> post_bulk_create.send(sender=self.model, objs=objs, batch_size
> =batch_size)
> return res
>
>
> class MyModel(models.Model):
> #...
> objects = MyModelQuerySet.as_manager()
>
>
>
> This gives us a nice interface to handle all kind of changes regarding 
> `MyModel`
> Our example usage looks like this:
>
>
> @receiver(pre_save, sender=MyModel)
> def my_handler(sender, **kwargs):
> instance = kwargs['instance']
> if instance.verified:
> do_something(instance)
> else:
> do_else(instance)
>
>
> @receiver(pre_bulk_update, sender=MyModel)
> def my_bulk_update_handler(sender, **kwargs):
> update_kwargs = kwargs['update_kwargs']
> if 'verified' not in update_kwargs:
> # no change im interested in
> # no need to take any action
> return
>
> queryset = kwargs['queryset']
> pks_to_be_updated = queryset.values_list('pk', flat=True)
> if update_kwargs['verified']:
> do_something_bulk_update_implementation(pks_to_be_updated)
> else:
> bulk_update_do_else_implementation(pks_to_be_updated)
>
>
> @receiver(pre_bulk_create, sender=MyModel)
> def my_bulk_create_handler(sender, **kwargs):
> objs = kwargs['objs']
> group_1 = []
> group_2 = []
> for obj in objs:
> if obj.verified:
> group_1.append(obj)
> else:
> group_2.append(obj)
>
> if group_1:
> do_something_bulk_create_implementation(group_1)
> if group_2:
> bulk_create_do_else_implementation(group_2)
>
>
>
> I think this turns out to be a very clean approach.
> It help us use the most optimal strategy to handle the change.
> So I'm sharing this with the community to check your feedback.
> I believe if this gets into the Django Internals, it can be a very 
> powerful tool.
> It will lose power as a 3rd party app.
>

-- 
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/81796184-84b8-4954-900a-2bf9ce965fe8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Add better support for ManyToMany with intermediary table fields, and reverse relationships, specially in forms

2017-03-30 Thread Gabriel Canto
When you are creating a system from scratch, coming with a ideal and 
organized model is simple enough, but when you are trying to replicate a 
real world system/issue into your models, things get complicated.

By complicated I mean, almost every relationship is a M2M with intermediary 
fields, that's the issue I'm trying to solve using Django, real world 
documents, contracts, people.

The main concern is making the CRUD web app easy for the user eyes.

Django really made things difficult, specially because in our context the 
relationship direction doesn't matter, we want both forward and reverse 
fields when editing an object


*First suggestion: give reverse relationships a common attribute for an 
easier way of getting them*

This is the code I had to make to get only reverse relationships of a 
model, it is very ugly and not my proudest work, but it works(so far)

 #I'm sure there's a better way of doing this
 #This is the documented way of getting reverse fields, but it also gets 
ManyToOne rel with the through table of forward m2m rels, so we have to 
filter them
 reverse_fields = [f for f in opts.get_fields() if f.auto_created and not f.
concrete]
 reverse_m2m = [f for f in reverse_fields if f.__class__.__name__ == 
'ManyToManyRel' and f.on_delete == None and not getattr(model,f.field.name,
False)]
 #Also filtering the ManyToOne rel with the through table of the reverse 
m2m rels, because we need to differentiate them from reverse ManyToOne with 
other models(not through)
 reverse_m2m_through = [f for f in reverse_fields if f.__class__.__name__ == 
'ManyToOneRel'  and f.related_model in [f.through for f in reverse_m2m if 
getattr(f,'through',False)]]
 forward_m2m = [f.remote_field for f in opts.get_fields() if not f.auto_created 
and f.many_to_many]
 #Filtering the ManyToOne rels with the through table of forwards m2m rels, 
same logic as above
 forward_m2m_through = [f for f in reverse_fields if f.__class__.__name__ == 
'ManyToOneRel'  and f.related_model in [f.through for f in forward_m2m if 
getattr(f,'through',False)]]
 reverse_fields_final = itertools.chain(reverse_m2m, [f for f in 
reverse_fields if f not in itertools.chain(reverse_m2m, reverse_m2m_through, 
forward_m2m, forward_m2m_through)])

*Second suggestion: following the first suggestion, give support to edit 
reverse rels in forms, and m2m with through tables*

An optional argument to ModelForm to also catch reverse relationships, 
using a specific form field for it, example : ReverseModelChoiceField, 
etc..., this can be done with just a simple changes to their forward 
counterpart classes

And, the most complex suggestion probably, is to add a form field to deal 
with M2M with through tables that contain intermediary fields, this can be 
done with a widget that is a table with inputs for cells, plus also work 
with reverse as suggested above, so I'm suggesting the creation of the 5 
following model form fields :


   1. ReverseModelChoiceField
   2. ReverseMultipleModelChoiceField
   3. ReverseManyToManyWithIntermediaryField (I'm sure there's a better 
   name)
   4. ManyToManyWithIntermediaryField

-- 
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/4b82d7d5-3a8d-4130-97b6-dff5423f9372%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Adding signals to bulk update/create operations

2017-03-30 Thread Todor Velichkov
Consider the following piece of code:

@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
instance = kwargs['instance']
if instance.verified:
do_something(instance)
else:
do_else(instance)



Its good, because it keeps `MyModel` decoupled from `do_something`

But there is one flaw. If we do:

MyModel.objects.filter(verified=False).update(verified=True)

we are screwed, `do_something` is not executed, and our models get 
out-of-sync.

If we try to get smart and manually fire the pre_save signal for each 
instance, we are gonna have a hard time.
Its gonna be slow.
And its gonna be memory inefficient.

We already experienced it in our app.

So our new approach is like this:

pre_bulk_update = Signal(providing_args=["queryset", "update_kwargs"])
post_bulk_update = Signal(providing_args=["update_kwargs",])

pre_bulk_create = Signal(providing_args=["objs", "batch_size"])
post_bulk_create = Signal(providing_args=["objs", "batch_size"])


class MyModelQuerySet(models.QuerySet):
def update(self, **kwargs):
pre_bulk_update.send(sender=self.model, queryset=self, 
update_kwargs=kwargs)
res = super(MyModelQuerySet, self).update(**kwargs)
# The queryset will be altered after the update call
# so no reason to send it.
post_bulk_update.send(sender=self.model, update_kwargs=kwargs)
return res

def bulk_create(self, objs, batch_size=None):
pre_bulk_create.send(sender=self.model, objs=objs, batch_size=
batch_size)
res = super(MyModelQuerySet, self).bulk_create(objs, batch_size)
post_bulk_create.send(sender=self.model, objs=objs, batch_size=
batch_size)
return res


class MyModel(models.Model):
#...
objects = MyModelQuerySet.as_manager()



This gives us a nice interface to handle all kind of changes regarding 
`MyModel`
Our example usage looks like this:


@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
instance = kwargs['instance']
if instance.verified:
do_something(instance)
else:
do_else(instance)


@receiver(pre_bulk_update, sender=MyModel)
def my_bulk_update_handler(sender, **kwargs):
update_kwargs = kwargs['update_kwargs']
if 'verified' not in update_kwargs:
# no change im interested in
# no need to take any action
return

queryset = kwargs['queryset']
pks_to_be_updated = queryset.values_list('pk', flat=True)
if update_kwargs['verified']:
do_something_bulk_update_implementation(pks_to_be_updated)
else:
bulk_update_do_else_implementation(pks_to_be_updated)


@receiver(pre_bulk_create, sender=MyModel)
def my_bulk_create_handler(sender, **kwargs):
objs = kwargs['objs']
group_1 = []
group_2 = []
for obj in objs:
if obj.verified:
group_1.append(obj)
else:
group_2.append(obj)

if group_1:
do_something_bulk_create_implementation(group_1)
if group_2:
bulk_create_do_else_implementation(group_2)



I think this turns out to be a very clean approach.
It help us use the most optimal strategy to handle the change.
So I'm sharing this with the community to check your feedback.
I believe if this gets into the Django Internals, it can be a very powerful 
tool.
It will lose power as a 3rd party app.

-- 
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/94257dee-e88c-41ae-ab39-c8535d8e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: A proposal for a new auto-reloader in Django

2017-03-30 Thread Carl Meyer
Anyone working on this project should at least be aware of
https://github.com/Pylons/hupper (based on work David Glick and I
originally did in https://github.com/carljm/wsgiwatcher), which aims to
be a framework-agnostic solution to this problem for any Python web
project. Docs at http://docs.pylonsproject.org/projects/hupper/en/latest/

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-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/af0d4ea6-e97e-522e-947a-83db87c6ebd0%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.


signature.asc
Description: OpenPGP digital signature


Re: A proposal for a new auto-reloader in Django

2017-03-30 Thread Aymeric Augustin
Hello,

> On 29 Mar 2017, at 01:05, qingnian...@gmail.com wrote:
> 
> the best library to replace Watchdog is Watchman, a library that supports 
> both of these three platforms (for Windows it's still in the alpha stage.)

Django currently doesn't use Watchdog. Watchdog is a cross-platform Python 
library that can be used for implementing an autoreloader. It's a plausible 
alternative to Watchman, likely easier to integrate, but Watchman has some 
fancy features that I'd love to have available -- like waiting for git to 
finish its operations before notifying a change.

> It runs as a standalone process and has a python wrapper library that is 
> incompatible with Python 3. Therefore, one of the goals is to figure out how 
> to interact with this library.

In order to be selected for this project, you have to convince us that you can 
solve this problem. At a minimum you must prove that you understand where the 
difficulties lie and suggest some possible approaches to tackle them.

> So my goals would be:
> 
>   • Replace the old auto-reloader with the Watchman version

Since installing watchman isn't trivial, you need to keep a pure-Python 
alternative so that beginners get an acceptable experience out of the box. This 
alternative may be the current "poll every second approach" or could be backed 
by watchdog, assuming it's pip-installable without complicated dependencies 
(e.g. a C compiler and development headers for a bunch of libraries) on all 
operating systems.

>   • Make sure that the new auto-reloader can work with Python3 and on 
> other platforms

Did you mean "work with Python 2" ? In any case, this isn't necessary, as you'd 
be working off the master branch which no longer supports Python 2.

>   • Make it compatible with other Python libraries
>   • Allow Django users to choose the files that should be watched
>   • Integrate the Watchman package and its Python wrapper into Django

Watchman should be installed separately by developers who wish to use it. 
Django should use it when it's available (and there should be a flag to disable 
that if for any reason someone has watchman installed systemwide but doesn't 
want to use it).

I hope this helps!

-- 
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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/F3334210-CCA2-4300-A368-6B48D596694B%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.