Re: Copy-from-base inheritance

2016-03-01 Thread Aymeric Augustin
Hello,

The “locally declared field gets overriden by parent definition” behavior shown 
in your example looks counter-intuitive to me.

Inheritance means that children inherit and possibly specialize their parent’s 
behavior, not that the parent overrides the child.

Best regards,

-- 
Aymeric.

> On 02 Mar 2016, at 01:57, Joakim Saario  wrote:
> 
> Hello!
> 
> I'd like to propose another inheritance strategy for django's models.
> 
> Think of it sort of like reversed abstract models
> 
> For example:
> 
> class NormalModel(models.Model):
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
> 
> class CopiedBaseModel(NormalModel):
> bar = models.CharField(max_length=2)
> buzz = models.CharField(max_length=10)
> 
> class Meta:
> copy_from_base = True
> 
> Would be equivalent to:
> 
> class NormalModel(models.Model):
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
> 
> class CopiedBaseModel(NormalModel):
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
> buzz = models.CharField(max_length=10)
> 
> My initial use case for this was with django-cms which didn't play well with
> multi-table inheritance when i needed to extend a built in plugin of theirs. 
> So
> I ended copying the whole model instead, which didn't make me too happy.
> So I started writing some code for the behaviour I was after. Which was,
> ironicly a standard python inheritance. Django only offers part of this 
> behaviour
> through the proxy and abstract models. But neither of them worked for me.
> 
> This is quite easy to implement with some of the current abstract model
> logic (see the 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 https://groups.google.com/group/django-developers 
> .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/django-developers/d4872520-eeb1-49a7-a8f3-aefc23a98346%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/EC21EA5B-60C2-4EBF-B85A-B00FA27AD5D8%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.


Re: Copy-from-base model inheritance.

2016-03-01 Thread Anssi Kääriäinen
The recommended way to do what you are after is:

class AbstractBase(models.Model):
f1 = models.IntegerField()

class Meta:
abstract = True

class Base(AbstractBase):
 pass

class Derived(AbstractBase):
f2 = models.IntegerField()


If you can't use the above way, then the way forward would be something like:

class Base(models.Model):
f1 = models.IntegerField()

class Derived(make_abstract(Base)):
f2 = models.IntegerField()

It might be possible to create the make_abstract() method outside of
Django. If not, we might be able to improve internals so that
make_abstract() would be easy to write outside of Django.

I don't think we want this inbuilt, as the make_abstract() model
design is inferior to using real abstract model as base for both
models.

 - Anssi

On Wed, Mar 2, 2016 at 2:30 AM, Joakim Saario  wrote:
> Hello!
>
> Wouldn't it be great to be able to inherit django models like any other
> python class? I.e not like the default multi-table inheritance.
>
> "How would this differ from an abstract model" you may ask. Well, it is sort
> of like an abstract model inheritance, except for the abstract part where
> the base model isn't registered
> and need to have abstract = True
>
> For example
>
> class NormalModel(models.Model):
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
>
> class CopiedBaseModel(NormalModel):
> buzz = models.CharField(max_length=10)
>
> class Meta:
> copy_from_base = True
>
>
> Would be equivalent to
>
> class NormalModel(models.Model):
>
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
>
> class CopiedBaseModel(NormalModel):
> foo = models.CharField(max_length=10)
> bar = models.CharField(max_length=10)
> buzz = models.CharField(max_length=10)
>
>
> My original use case for this was with django-cms, which didn't play well
> with the multi-table inheritance when I needed to extend a built in plugin
> of theirs. So I ended up copying the whole model.
> which annoyed me that it was the only way to do it.
>
> This also isolates the models from each other in constrast to multi-table
> inheritance, as the base class is just copied over to the new class, it
> shares this functionality with abstract models. Think of it as a kind of
> reverse abstract model. I wrote some code for this and actually reused much
> of the code used for abstract models. (see attatched 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 https://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/62b0b093-c7e5-4abb-a797-63277b31d27c%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/CALMtK1GEtPXYdA4c8Uv8Ss4YLHJ1XH%2Bv35NYH1uCEg2WGpm_Xw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Django admin and messages

2016-03-01 Thread Cristiano Coelho
Actual file with the issue: 
https://github.com/django/django/blob/master/django/contrib/admin/locale/es/LC_MESSAGES/django.po#L168

El martes, 1 de marzo de 2016, 22:42:05 (UTC-3), Cristiano Coelho escribió:
>
> Looking it deeper it seems mostly like a translation issue for the spanish 
> (and maybe other) languages, since in some cases both gender articles are 
> added ( "el/la" ) to make it generic but for the specific case I pointed 
> above it is missing.
>
>
> msgid ""
> "The %(name)s \"%(obj)s\" was added successfully. You may edit it again 
> below."
> msgstr ""
> "Se añadió con éxito el %(name)s \"%(obj)s. Puede editarlo de nuevo abajo."
>
> Should be changed to
>
> msgid ""
> "The %(name)s \"%(obj)s\" was added successfully. You may edit it again 
> below."
> msgstr ""
> "Se añadió con éxito el/la %(name)s \"%(obj)s. Puede editarlo/a de nuevo 
> abajo."
>
> The same happens for some other translations below this one. I couldn't 
> find why is it different for some and not for others, but "el/la" is 
> definitely better than "el" and having a female object following it.
> Another approach for gender languages like spanish would be to use "el 
> objeto %(obj)" rather than "el/la %(obj)".
>
>
>
> El sábado, 20 de febrero de 2016, 16:51:27 (UTC-3), Cristiano Coelho 
> escribió:
>>
>> Hello, 
>>
>> It seems that all admin "sucess" (and others) messages are hardcoded 
>> (almost, actually translations) into the methods that use them and can not 
>> be easily changed (like 'The %(name)s "%(obj)s" was added successfully. You 
>> may add another %(name)s below.').
>> This is causing some issues on languages with higher gender usage, like 
>> spanish, that you can get into texts like 'El Persona "Id: 123" .' 
>> (should be La Persona), so it would be convenient to be able to easily 
>> change these messages so you could just change it to "Object added 
>> successfully" or something to prevent the above issue.
>>
>> Looking through the file django/contrib/admin/options.py you can see the 
>> huge usage of texts defined deep into the methods, which makes it 
>> impossible to override any of them.
>>
>

-- 
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/f626ae8c-905b-447c-a355-055caee7187d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Django admin and messages

2016-03-01 Thread Cristiano Coelho
Looking it deeper it seems mostly like a translation issue for the spanish 
(and maybe other) languages, since in some cases both gender articles are 
added ( "el/la" ) to make it generic but for the specific case I pointed 
above it is missing.


msgid ""
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again 
below."
msgstr ""
"Se añadió con éxito el %(name)s \"%(obj)s. Puede editarlo de nuevo abajo."

Should be changed to

msgid ""
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again 
below."
msgstr ""
"Se añadió con éxito el/la %(name)s \"%(obj)s. Puede editarlo/a de nuevo 
abajo."

The same happens for some other translations below this one. I couldn't 
find why is it different for some and not for others, but "el/la" is 
definitely better than "el" and having a female object following it.
Another approach for gender languages like spanish would be to use "el 
objeto %(obj)" rather than "el/la %(obj)".



El sábado, 20 de febrero de 2016, 16:51:27 (UTC-3), Cristiano Coelho 
escribió:
>
> Hello, 
>
> It seems that all admin "sucess" (and others) messages are hardcoded 
> (almost, actually translations) into the methods that use them and can not 
> be easily changed (like 'The %(name)s "%(obj)s" was added successfully. You 
> may add another %(name)s below.').
> This is causing some issues on languages with higher gender usage, like 
> spanish, that you can get into texts like 'El Persona "Id: 123" .' 
> (should be La Persona), so it would be convenient to be able to easily 
> change these messages so you could just change it to "Object added 
> successfully" or something to prevent the above issue.
>
> Looking through the file django/contrib/admin/options.py you can see the 
> huge usage of texts defined deep into the methods, which makes it 
> impossible to override any of them.
>

-- 
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/f0802f7e-f47f-4636-baa8-f9274f4eaeaa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [Question] jsi18n - get_javascript_catalog a bit obscure?

2016-03-01 Thread Cristiano Coelho
Looking through git history seems like the "always load english 
translations" code is quite a few years old.

There's a 5 y.o ticket in here: https://code.djangoproject.com/ticket/16284

Which leads to here: https://code.djangoproject.com/ticket/3594 with a fix 
that adds the "discard if english not found" which doesn't resolve the 
issue completely if you actually have english translations but it is not 
the default language.

There's also a link to here: 
https://groups.google.com/forum/#!topic/django-developers/1X_tPbhG_NQ 
proposing a change with no replies at all.

I couldn't really understand why is it that the hardcoded english language 
can not be removed from here.

In my opinion the code should be slightly changed to only load the default 
language rather than english (and as long as the requested language is not 
the same as the default one) as fallback, so it can match the actual server 
side behaviour, which will load the configured language (at settings) as a 
fallback language as long as it is different from it (an from english, 
which makes sense because django text ids are all in english).
This change could however affect people that relies on always having an 
english translation as fallback when the configured default language is not 
english (does this even make sense? Would anyone do that?)

After this change is done, there could be an improvement (for both js and 
server side translations) that some people might find useful, rather than 
always falling back to the default configured language, you could have a 
map of fallbacks, for example, if the user requests a portuguese language, 
but you only have english (default) and spanish (secondary), it makes more 
sense to fallback to spanish rather than english, but if the user requests 
russian, it makes more sense to fallback to english.

El martes, 1 de marzo de 2016, 21:29:42 (UTC-3), Tim Graham escribió:
>
> Have you tried looking through history with git blame to find related 
> tickets? Another tip is to search Google with a query like 
> "javascript_catalog site:code.djangoproject.com". This will let you find 
> tickets to see if the issue was raised before. This is how I try to answer 
> questions like this since many of the original authors are no longer active 
> (or at least, you can find the person who authored the code in question and 
> try a more directed query like a ping in IRC).
>
> On Tuesday, March 1, 2016 at 6:23:38 PM UTC-5, Cristiano Coelho wrote:
>>
>> Maybe I wasn't clear neither, but the main issue is this: when using a 
>> language equals to the default one, and if that language does not define 
>> any translation text (because ids are the same as values so it is not 
>> necessary), the server side translations will always correctly return the 
>> translated texts, while the javascript won't because it always has an 
>> english fallback.
>> Also the code I provided should actually load the default language 
>> translations as well (but not the english ones!) to make it behave exactly 
>> as the server side translations.
>>
>

-- 
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/1387d9aa-7e51-43ff-a88c-f81242ce799a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Should tutorial start with minimal Django?

2016-03-01 Thread Curtis Maloney
When we were teaching MelbDjango, I did start by writing views in the 
root urls.py  this avoided students having to create a bunch of 
files and apps and references and imports and...


For some of the students transitioning from PHP, it was much easier to 
deal with only learning one thing at a time...


However, we didn't go quite so far as that example... still using 
"startproject" etc.


--
Curtis

On 02/03/16 12:03, Bobby Mozumder wrote:

Hi,

Here’s an example of minimal Django, where one can output run an full site from 
a single file:
  https://github.com/rnevius/minimal-django

The author made the comparison to Flask.

I believe the tutorial should start out with this, as the initial Part 0, to 
introduce the audience to the framework, before introducing 
apps/models/subdirectories/etc.  I think a lot of people are turned off by the 
heavy-handed immediate introduction of many files and directories of a Django 
setup - I know I was when I first started with Django.

Anyways just putting this out there.

-bobby



--
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/56D63CBD.1070501%40tinbrain.net.
For more options, visit https://groups.google.com/d/optout.


Should tutorial start with minimal Django?

2016-03-01 Thread Bobby Mozumder
Hi,

Here’s an example of minimal Django, where one can output run an full site from 
a single file:
 https://github.com/rnevius/minimal-django

The author made the comparison to Flask.

I believe the tutorial should start out with this, as the initial Part 0, to 
introduce the audience to the framework, before introducing 
apps/models/subdirectories/etc.  I think a lot of people are turned off by the 
heavy-handed immediate introduction of many files and directories of a Django 
setup - I know I was when I first started with Django.

Anyways just putting this out there.

-bobby

-- 
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/33F74D49-8220-4F74-96A8-1AD4740A7D88%40gmail.com.
For more options, visit https://groups.google.com/d/optout.


Copy-from-base inheritance

2016-03-01 Thread Joakim Saario
Hello!

I'd like to propose another inheritance strategy for django's models.

Think of it sort of like reversed abstract models

For example:

class NormalModel(models.Model):
foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
bar = models.CharField(max_length=2)
buzz = models.CharField(max_length=10)

class Meta:
copy_from_base = True

Would be equivalent to:

class NormalModel(models.Model):
foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)
buzz = models.CharField(max_length=10)

My initial use case for this was with django-cms which didn't play well with
multi-table inheritance when i needed to extend a built in plugin of 
theirs. So
I ended copying the whole model instead, which didn't make me too happy.
So I started writing some code for the behaviour I was after. Which was,
ironicly a standard python inheritance. Django only offers part of this 
behaviour
through the proxy and abstract models. But neither of them worked for me.

This is quite easy to implement with some of the current abstract model
logic (see the 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/d4872520-eeb1-49a7-a8f3-aefc23a98346%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 8cc9599..7c0f34a 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -188,20 +188,24 @@ class ModelBase(type):
 else:
 new_class._meta.concrete_model = new_class
 
-# Collect the parent links for multi-table inheritance.
-parent_links = {}
-for base in reversed([new_class] + parents):
-# Conceptually equivalent to `if base is Model`.
-if not hasattr(base, '_meta'):
-continue
-# Skip concrete parent classes.
-if base != new_class and not base._meta.abstract:
-continue
-# Locate OneToOneField instances.
-for field in base._meta.local_fields:
-if isinstance(field, OneToOneField):
-related = resolve_relation(new_class, field.remote_field.model)
-parent_links[make_model_tuple(related)] = field
+should_copy_from_base = getattr(new_class._meta, 'copy_from_base', False)
+
+if not should_copy_from_base:
+# Collect the parent links for multi-table inheritance.
+parent_links = {}
+for base in reversed([new_class] + parents):
+# Conceptually equivalent to `if base is Model`.
+if not hasattr(base, '_meta'):
+continue
+# Skip concrete parent classes.
+if base != new_class and not base._meta.abstract:
+continue
+# Locate OneToOneField instances.
+for field in base._meta.local_fields:
+if isinstance(field, OneToOneField):
+related = resolve_relation(new_class, field.remote_field.model)
+parent_links[make_model_tuple(related)] = field
+
 # Do the appropriate setup for any model parents.
 for base in parents:
 original_base = base
@@ -211,17 +215,19 @@ class ModelBase(type):
 continue
 
 parent_fields = base._meta.local_fields + base._meta.local_many_to_many
-# Check for clashes between locally declared fields and those
-# on the base classes (we cannot handle shadowed fields at the
-# moment).
-for field in parent_fields:
-if field.name in field_names:
-raise FieldError(
-'Local field %r in class %r clashes '
-'with field of similar name from '
-'base class %r' % (field.name, name, base.__name__)
-)
-if not base._meta.abstract:
+if not should_copy_from_base:
+# Check for clashes between locally declared fields and those
+# on the base classes (we cannot handle shadowed fields at the
+# moment).
+for field in parent_fields:
+if field.name in field_names:
+  

Copy-from-base model inheritance.

2016-03-01 Thread Joakim Saario
Hello!

Wouldn't it be great to be able to inherit django models like any other 
python class? I.e not like the default multi-table inheritance.

"How would this differ from an abstract model" you may ask. Well, it is 
sort of like an abstract model inheritance, except for the abstract part 
where the base model isn't registered
and need to have abstract = True

*For example*

class NormalModel(models.Model):
foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
buzz = models.CharField(max_length=10)

class Meta:
copy_from_base = True


Would be equivalent to

class NormalModel(models.Model):

foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)

class CopiedBaseModel(NormalModel):
foo = models.CharField(max_length=10)
bar = models.CharField(max_length=10)
buzz = models.CharField(max_length=10)


My original use case for this was with django-cms, which didn't play well 
with the multi-table inheritance when I needed to extend a built in plugin 
of theirs. So I ended up copying the whole model.
which annoyed me that it was the only way to do it.

This also isolates the models from each other in constrast to multi-table 
inheritance, as the base class is just copied over to the new class, it 
shares this functionality with abstract models. Think of it as a kind of 
reverse abstract model. I wrote some code for this and actually reused much 
of the code used for abstract models. (see attatched 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/62b0b093-c7e5-4abb-a797-63277b31d27c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 8cc9599..7c0f34a 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -188,20 +188,24 @@ class ModelBase(type):
 else:
 new_class._meta.concrete_model = new_class
 
-# Collect the parent links for multi-table inheritance.
-parent_links = {}
-for base in reversed([new_class] + parents):
-# Conceptually equivalent to `if base is Model`.
-if not hasattr(base, '_meta'):
-continue
-# Skip concrete parent classes.
-if base != new_class and not base._meta.abstract:
-continue
-# Locate OneToOneField instances.
-for field in base._meta.local_fields:
-if isinstance(field, OneToOneField):
-related = resolve_relation(new_class, field.remote_field.model)
-parent_links[make_model_tuple(related)] = field
+should_copy_from_base = getattr(new_class._meta, 'copy_from_base', False)
+
+if not should_copy_from_base:
+# Collect the parent links for multi-table inheritance.
+parent_links = {}
+for base in reversed([new_class] + parents):
+# Conceptually equivalent to `if base is Model`.
+if not hasattr(base, '_meta'):
+continue
+# Skip concrete parent classes.
+if base != new_class and not base._meta.abstract:
+continue
+# Locate OneToOneField instances.
+for field in base._meta.local_fields:
+if isinstance(field, OneToOneField):
+related = resolve_relation(new_class, field.remote_field.model)
+parent_links[make_model_tuple(related)] = field
+
 # Do the appropriate setup for any model parents.
 for base in parents:
 original_base = base
@@ -211,17 +215,19 @@ class ModelBase(type):
 continue
 
 parent_fields = base._meta.local_fields + base._meta.local_many_to_many
-# Check for clashes between locally declared fields and those
-# on the base classes (we cannot handle shadowed fields at the
-# moment).
-for field in parent_fields:
-if field.name in field_names:
-raise FieldError(
-'Local field %r in class %r clashes '
-'with field of similar name from '
-'base class %r' % (field.name, name, base.__name__)
-)
-if not base._meta.abstract:
+if not should_copy_from_base:
+# Check for clashes betw

Re: [Question] jsi18n - get_javascript_catalog a bit obscure?

2016-03-01 Thread Tim Graham
Have you tried looking through history with git blame to find related 
tickets? Another tip is to search Google with a query like 
"javascript_catalog site:code.djangoproject.com". This will let you find 
tickets to see if the issue was raised before. This is how I try to answer 
questions like this since many of the original authors are no longer active 
(or at least, you can find the person who authored the code in question and 
try a more directed query like a ping in IRC).

On Tuesday, March 1, 2016 at 6:23:38 PM UTC-5, Cristiano Coelho wrote:
>
> Maybe I wasn't clear neither, but the main issue is this: when using a 
> language equals to the default one, and if that language does not define 
> any translation text (because ids are the same as values so it is not 
> necessary), the server side translations will always correctly return the 
> translated texts, while the javascript won't because it always has an 
> english fallback.
> Also the code I provided should actually load the default language 
> translations as well (but not the english ones!) to make it behave exactly 
> as the server side translations.
>

-- 
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/1a47cef8-395b-4bf4-8c0b-41e3e4e885bc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [Question] jsi18n - get_javascript_catalog a bit obscure?

2016-03-01 Thread Cristiano Coelho
Maybe I wasn't clear neither, but the main issue is this: when using a 
language equals to the default one, and if that language does not define 
any translation text (because ids are the same as values so it is not 
necessary), the server side translations will always correctly return the 
translated texts, while the javascript won't because it always has an 
english fallback.
Also the code I provided should actually load the default language 
translations as well (but not the english ones!) to make it behave exactly 
as the server side translations.

-- 
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/52a1741e-5059-4d91-926b-1a2fa924fbcd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[Question] jsi18n - get_javascript_catalog a bit obscure?

2016-03-01 Thread Cristiano Coelho
https://github.com/django/django/blob/master/django/views/i18n.py#L204

Can someone explain me why does it have to always load english as the first 
fallback?

Also, line 248:

 # If the currently selected language is English but it doesn't have a
 # translation catalog (presumably due to being the language translated
 # from) then a wrong language catalog might have been loaded in the
 # previous step. It needs to be discarded.

Looks unnecessary hard.

On a project, I had to monkey patch this method because I didn't add 
translations at all for my default language (not english) since the 
identifiers was enough, and for all the server side translations it worked 
fine. However, for javascript translations, since english was one of my 
translations, I would end up getting english translated strings when I was 
expecting the default identifier to be returned. So to fix it I just 
removed all the english and default languages loading and everything worked 
as expected. What would be the issues with this? Was there actually another 
approach?

Below is my slightly changed code of this method (I did it quite a few ago 
but surfaced again for some reason), I would like to know if it makes sense 
and the original code really has some obscure logic or I'm missing 
something important about it.

def get_javascript_catalog(locale, domain, packages):
default_locale = to_locale(settings.LANGUAGE_CODE)
app_configs = apps.get_app_configs()
allowable_packages = set(app_config.name for app_config in app_configs)
allowable_packages.add('django.conf')
packages = [p for p in packages if p in allowable_packages]
t = {}
paths = []
 
# paths of requested packages
for package in packages:
p = importlib.import_module(package)
path = os.path.join(os.path.dirname(upath(p.__file__)), 'locale')
paths.append(path)
# add the filesystem paths listed in the LOCALE_PATHS setting
paths.extend(list(reversed(settings.LOCALE_PATHS)))
 
   
locale_t = {}
for path in paths:
try:
catalog = gettext_module.translation(domain, path, [locale])
except IOError:
catalog = None
if catalog is not None:
locale_t.update(catalog._catalog)
 
if locale_t:
t = locale_t
plural = None
if '' in t:
for l in t[''].split('\n'):
if l.startswith('Plural-Forms:'):
plural = l.split(':', 1)[1].strip()
if plural is not None:
# this should actually be a compiled function of a typical plural-form:
# Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 
&& n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
plural = [el.strip() for el in plural.split(';') if 
el.strip().startswith('plural=')][0].split('=', 1)[1]
 
pdict = {}
maxcnts = {}
catalog = {}
for k, v in t.items():
if k == '':
continue
if isinstance(k, six.string_types):
catalog[k] = v
elif isinstance(k, tuple):
msgid = k[0]
cnt = k[1]
maxcnts[msgid] = max(cnt, maxcnts.get(msgid, 0))
pdict.setdefault(msgid, {})[cnt] = v
else:
raise TypeError(k)
for k, v in pdict.items():
catalog[k] = [v.get(i, '') for i in range(maxcnts[msgid] + 1)]
 
return catalog, plural






-- 
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/bc9894cf-b657-4d10-94e8-9eea7a9234ed%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Override the default form field for a model field

2016-03-01 Thread James Pic
Hi all,

Currently, the model field defines the default form field that's used
by the modelform metaclass. It would be nice if an external app could
overwrite this.

For example, a user installs an app which provides a more elaborated
relation select field. They configure the app to be able provide a
better form field or widget to select a particular model.

Now, it's a bit boilerplate to override the default generated form
field for a relation to that model in every modelform, as such:

class FirstForm(forms.ModelForm):
group = BetterField(your_options)

class SecondForm(forms.ModelForm):
main_group = BetterField(your_options)

# and so on

Currently, forms.ModelForm will use a form field that's known to work
by default. It does so by delegating that logic to the model field
methods such formfield() & friends.

Perhaps it would be an improvement if forms.ModelForm would be able to
use a form field that's *best* by default. "Best" here, is defined by
the project: what optional apps are installed and what configuration
they have.

For example, some apps will focus on providing a specific business
logic field, virtual or not (ie. generic many to many, array field,
tagfield ...), and other apps would focus on specific UX
(autocompletion, popup selection like raw_id_fields, other kind of
AJAX widgets). Gluing these apps in a projects is always the same,
from a project to another. If this kind of glue could be encapsulated
in another app, and made available in forms.ModelForm to improve
defaults, then users would have more time to work on what makes their
project different, rather than the same boilerplate code over and over
again.

I've been experimenting with ways to mitigate this issue for a few
years now, and here's what I came up with:

- allow a form field to override the model field's default saving
logic, as the input format may change it:
ModelField.value_from_object(), ModelField.save_form_data() and
ModelField.save_relation_data() should be overidable by the form
field,
- allow an app to register "form field factory callbacks" to ModelFormMetaclass

I've implemented all that in a separate app and experimented with it
for a while, and TBH it works and it's okay to have this in an
external app rather than in Django itself (PoC:
https://github.com/jpic/xmodelform ), even thought it implies that the
user has to override everything to use this ModelForm by default
(admin, views, forms ...), this is not known to have killed any kitten
so far. Unless some point out that it would be good to have it in
Django, I'd work on it in a separate app 

BUT, before I go all-in with this and make users use it by providing
it as the "official way", there's still one thing that fails to
convince me that it's the way to go. Something that may seem
completely unrelated, because it's a completely different way to go,
but solves the same issue: shouldn't effort be put in making a proper
way to change model fields from an external app ?

Related research on this has been started already apparently, with
django-swappable-models. It seems like work has been started to enable
model class override. While that's obviously overkill in the case I'm
talking about here, I'm wondering: would it be better to research a
way to enable external model field override, rather than the
form-oriented design exposed above (xmodelform) ?

I wish this could be avoided, but I recon that when you've tried
django-autocomplete-light v2's ModelForm, it's like eating the
defended fruit. Most of our userbase consider that v3 is not complete
and won't upgrade from v2 until they have this feature. I can
understand them, having a ModelForm that generates form fields which
are beyond "known to work" and have it generate "best" form fields for
a project without any boilerplate code is damn beautiful to see.
That's why this issue has been so fascinating to me and at least those
from the user base who stood up for that.

So, all this considered, what do you prefer, 0. research on overriding
the model field, or 1. on the model form ?

If 1., can we add the possibility to override the default ModelForm
class used by modelform_factory() and friends in Django ?

Thanks in advance for your guidance.

Best

-- 
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/CALC3KaczUhnW4onQ%2B8qz3EZyHcD6%3Dxcap%2BPCuCxg6AvXCNRpCQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


[ANNOUNCE] Django security releases issued: 1.9.3 and 1.8.10

2016-03-01 Thread Tim Graham
Today the Django team issued 1.9.3 and 1.8.10 as part of our security 
process. This releases address two security issues, and we encourage all 
users to upgrade as soon as possible.

Details are available on the Django project weblog:

https://www.djangoproject.com/weblog/2016/mar/01/security-releases/

As a reminder, we ask that potential security issues be reported via 
private email to secur...@djangoproject.com and not via Django's Trac 
instance or the django-developers list. Please see 
https://www.djangoproject.com/security for further information.

-- 
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/7dc04e47-533c-46cb-b9e0-eee3367e6f81%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.