Monday, October 28, 2013

Re: Backwards relation not showing up via related_name in inherited models

Thank you for responding, that's extremely helpful.  I'm still failing to query against it though.  How would I implement a query for the get_children() method in the example above?  That is, for any given instance of FlowBlueprint how do I get all objects with a relation to it?

On Monday, October 28, 2013 6:56:40 AM UTC-5, Daniel Roseman wrote:
On Monday, 28 October 2013 07:29:39 UTC, Joshua Orvis wrote:
I'm using Django 1.6 RC1 and Python 3.3 with the following models:

class StepBlueprint(models.Model):
    parents = models.ManyToManyField('self', blank=True, null=True, related_name='children')
    name   = models.CharField( max_length=100 )

    def __str__(self):
        return self.name

class FlowBlueprint(StepBlueprint):
    description = models.TextField()
        
    def get_children(self):
        print("DEBUG: processing ({0})".format(self))
        print(dir(self))

        # why isn't this working??  this is what related_name is supposed to provide
        return self.children

When I call get_children() here, I get the following:

DEBUG: processing (Prodigal)
['DoesNotExist', 'MultipleObjectsReturned', 'TYPES', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_base_manager', '_default_manager', '_deferred', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', '_state', 'build', 'clean', 'clean_fields', 'commandblueprint', 'conditional_code', 'date_error_message', 'delete', 'description', 'flow_set', 'flowblueprint', 'full_clean', 'get_children', 'get_command', 'get_type_display', 'id', 'name', 'objects', 'parents', 'pk', 'prepare_database_save', 'save', 'save_base', 'serializable_value', 'standalonetool_set', 'stepblueprint_ptr', 'stepblueprint_ptr_id', 'type', 'unique_error_message', 'validate_unique']
Traceback (most recent call last):
  [ call stack ... ]
    return self.children
AttributeError: 'FlowBlueprint' object has no attribute 'children'

What am I doing wrong here?  From within the FlowBlueprint object I want to be able to get the backwards relation of all those objects pointing to it, and it seems like related_name is supposed to provide that.  Its value doesn't show up in the dir() output.

Any help would be greatly appreciated.


This has nothing to do with inheritance - you would get the same result if you called `self.children` from StepBlueprint.

See the documentation on many-to-many relationships with self:
(emphasis added):

"When Django processes this model, it identifies that it has a ManyToManyField on itself, and as a result, it **doesn't add a person_set attribute to the Person class**. Instead, the ManyToManyField is assumed to be symmetrical – that is, if I am your friend, then you are my friend.
If you do not want symmetry in many-to-many relationships with self, set symmetrical to False. This will force Django to add the descriptor for the reverse relationship, allowing ManyToManyField relationships to be non-symmetrical."
--
DR.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/66e5ec75-040b-4c36-85da-85af7365e9f2%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment