Search code examples
pythondjangoforeign-keysmanytomanyfieldlimit-choices-to

Django MTMField: limit_choices_to = other_ForeignKeyField_on_same_model?


I've got a couple django models that look like this:

from django.contrib.sites.models import Site

class Photo(models.Model):
    title = models.CharField(max_length=100)
    site = models.ForeignKey(Site)
    file = models.ImageField(upload_to=get_site_profile_path) 

    def __unicode__(self):
        return self.title


class Gallery(models.Model):    
    name = models.CharField(max_length=40)
    site = models.ForeignKey(Site)
    photos = models.ManyToManyField(Photo, limit_choices_to = {'site':name} )    

    def __unicode__(self):
        return self.name

I'm having all kinds of fun trying to get the limit_choices_to working on the Gallery model. I only want the Admin to show choices for photos that belong to the same site as this gallery. Is this possible?


Solution

  • I would delete site field on my Photo model and add a ForeignKey to Gallery. I would remove limit_choices_to from photos fields on Gallery model.

    Because you are using ForeignKeys to Sites, that means sites don't share galleries and photos. Therefore having those I mentioned above is already useless.

    class Photo(models.Model):
        title = models.CharField(max_length=100)
        gallery = models.ForeignKey(Gallery, related_name='photos')
        file = models.ImageField(upload_to=get_site_profile_path) 
    
        def __unicode__(self):
            return self.title
    
    
    class Gallery(models.Model):    
        name = models.CharField(max_length=40)
        site = models.ForeignKey(Site)
    
        def __unicode__(self):
            return self.name
    

    Once you set the site on a gallery all its photos will inherit this property. And the site will be accessible as photo_instance.gallery.site:

    @property
    def site(self):
        return self.gallery.site
    

    This should work as if you had a site field. But I haven't tested it.

    Things change or course, if you decide that a gallery or a photo can appear in multiple sites.