Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 825
saturdayplace Avatar asked Dec 05 '08 22:12

saturdayplace


2 Answers

Yes. You need to override the form that admin uses for the Gallery model, then limit the queryset of the photos field in that form:

class GalleryAdminForm(django.forms.ModelForm):

    class Meta:
        model = Gallery

    def __init__(self, *args, **kwargs):
        super(GalleryAdminForm, self).__init__(*args, **kwargs)
        self.fields['segments'].queryset = Photo.objects.filter(site=self.instance.site)


class GalleryAdmin(django.contrib.admin.ModelAdmin):
    form = GalleryAdminForm

django.contrib.admin.site.register(Gallery, GalleryAdmin)
like image 69
Vebjorn Ljosa Avatar answered Oct 28 '22 03:10

Vebjorn Ljosa


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.

like image 31
muhuk Avatar answered Oct 28 '22 05:10

muhuk