[mezzanine-users] Re: EXTRA_MODEL_FIELDS - ForeignKey to self

2015-02-20 Thread Mathias Ettinger
I guess it’s because both EXTRA_MODEL_FIELDS and strings referencing 
classes as ForeignKey positional argument rely on the class_prepared 
signal. But with it being only sent once, the ForeignKey doesn't have any 
chance to catch the signal in time.

For every other use case other than a self-referencing ForeignKey, either 
the model being referenced has been created when the extra ForeignKey is 
added and it can be resolved as a class right away, or the ForeignKey will 
be able to resolve the class as soon as it send the class_prepared signal.
In the case of a self-referencing extra ForeignKey, the ForeignKey is added 
after the class_prepared signal has been fired but can't resolve the string 
into a class yet because the model has not finished initializing. So the 
ForeignKey connect to the class_prepared signal and wait for the class that 
just fired it to fire it "again". In vain.

One solution could be to re-raise the class_prepared signal after extra 
fields had been added to a model. To do so, you could change the 
add_extra_model_fields function in mezzanine/boot/__init__.py to:
def add_extra_model_fields(sender, **kwargs):
"""
Injects custom fields onto the given sender model as defined
by the ``EXTRA_MODEL_FIELDS`` setting.
"""
model_path = "%s.%s" % (sender.__module__, sender.__name__)
extra_fields = fields.get(model_path, {})
if (extra_fields):
for field_name, field in extra_fields.items():
field.contribute_to_class(sender, field_name)
del fields[model_path]
# re-send the class_prepared signal so self-referencing ForeignKey 
can catch up
class_prepared.send(sender=sender)


Le vendredi 20 février 2015 17:44:37 UTC+1, Kacper Kołodziej a écrit :
>
> Hi! I'm trying to create multi-level categories structure. I have added 
> ForeignKey to 'self' to BlogCategory. I've tried to do it in some different 
> ways: http://pastebin.com/77ex9ehe but none of them works. I always 
> receive error on syncdb:
>
> CommandError: One or more models did not validate:
>> blog.blogcategory: 'parent_category' has a relation with model self, 
>> which has either not been installed or is abstract.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mezzanine-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[mezzanine-users] Re: EXTRA_MODEL_FIELDS - ForeignKey to self

2015-08-28 Thread Matt Hughes
anyway to implement this without changing 'boot/__init__' directly?

On Friday, February 20, 2015 at 4:50:57 PM UTC-5, Mathias Ettinger wrote:
>
> I guess it’s because both EXTRA_MODEL_FIELDS and strings referencing 
> classes as ForeignKey positional argument rely on the class_prepared 
> signal. But with it being only sent once, the ForeignKey doesn't have any 
> chance to catch the signal in time.
>
> For every other use case other than a self-referencing ForeignKey, either 
> the model being referenced has been created when the extra ForeignKey is 
> added and it can be resolved as a class right away, or the ForeignKey will 
> be able to resolve the class as soon as it send the class_prepared signal.
> In the case of a self-referencing extra ForeignKey, the ForeignKey is 
> added after the class_prepared signal has been fired but can't resolve the 
> string into a class yet because the model has not finished initializing. So 
> the ForeignKey connect to the class_prepared signal and wait for the class 
> that just fired it to fire it "again". In vain.
>
> One solution could be to re-raise the class_prepared signal after extra 
> fields had been added to a model. To do so, you could change the 
> add_extra_model_fields function in mezzanine/boot/__init__.py to:
> def add_extra_model_fields(sender, **kwargs):
> """
> Injects custom fields onto the given sender model as defined
> by the ``EXTRA_MODEL_FIELDS`` setting.
> """
> model_path = "%s.%s" % (sender.__module__, sender.__name__)
> extra_fields = fields.get(model_path, {})
> if (extra_fields):
> for field_name, field in extra_fields.items():
> field.contribute_to_class(sender, field_name)
> del fields[model_path]
> # re-send the class_prepared signal so self-referencing ForeignKey 
> can catch up
> class_prepared.send(sender=sender)
>
>
> Le vendredi 20 février 2015 17:44:37 UTC+1, Kacper Kołodziej a écrit :
>>
>> Hi! I'm trying to create multi-level categories structure. I have added 
>> ForeignKey to 'self' to BlogCategory. I've tried to do it in some different 
>> ways: http://pastebin.com/77ex9ehe but none of them works. I always 
>> receive error on syncdb:
>>
>> CommandError: One or more models did not validate:
>>> blog.blogcategory: 'parent_category' has a relation with model self, 
>>> which has either not been installed or is abstract.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mezzanine-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.