Hello all,

I'll illustrate my problem with a small example.

Let's consider a data model:

--------------------------------------------------------------
from django.db import models

class OldTag(models.Model):
    content = models.TextField()

class NewTag(models.Model):
   content = models.TextField()
   oldtags = models.ManyToManyField(OldTag)

class Document(models.Model):
    content = models.TextField()
    oldtags = models.ManyToManyField(OldTag)
--------------------------------------------------------------

So there are two many-to-many relationships between classes.

I'd like to find all the documents that are related to a specific new
tag. To reach the new tags, I need to pass old tags first, do I'd expect
to use something like this:

>>> Document.objects.filter(oldtags__newtags__content = 'popcorn')

But it doesn't work:
TypeError: Cannot resolve keyword 'newtags' into field

Let's consider an example data:

--------------------------------------------------------------
from myproject.myapp.models import OldTag, NewTag, Document

d, dc = Document.objects.get_or_create(content = "spam")
d.save()
ot, otc = OldTag.objects.get_or_create(content = "eggs")
ot.save()
nt, ntc = NewTag.objects.get_or_create(content = "popcorn")
nt.save()
d.oldtags.add(ot)
nt.oldtags.add(ot)
--------------------------------------------------------------

I can easily find all the documents with the specified old tag:

>>> Document.objects.filter(oldtags__content = 'eggs')

To find the field that I could access with the filter, I look inside the
old tag object:

>>> dir(ot)
['AddManipulator', 'ChangeManipulator', 'DoesNotExist', '__class__',
'__delattr__', '__dict__', '__doc__', '__eq__', '__getattribute__',
'__hash__', '__init__', '__metaclass__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', '__weakref__', '_collect_sub_objects', '_default_manager',
'_get_FIELD_display', '_get_FIELD_filename', '_get_FIELD_height',
'_get_FIELD_size', '_get_FIELD_url', '_get_FIELD_width',
'_get_image_dimensions', '_get_next_or_previous_by_FIELD',
'_get_next_or_previous_in_order', '_get_pk_val', '_meta', '_prepare',
'_save_FIELD_file', '_set_related_many_to_many', 'add_to_class',
'content', 'delete', 'document_set', 'id', 'newtag_set', 'objects',
'save', 'validate']

So there's something called newtag_set in the old tag object. It allows
to fetch all the new tags related to the old tag. I managed to get what
I want with this expression:

>>> Document.objects.filter(oldtags__in = NewTag.objects.get(content = 
>>> 'popcorn').oldtags.all())

...but it executes two SQL queries, while it can be done with just one
query. Do you have any better ideas?

Regards,
Maciej

-- 
Maciej Bliziński
http://automatthias.wordpress.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to