Django MTMField: limit_choices_to = other_ForeignKeyField_on_same_model?

安稳与你 提交于 2019-12-06 03:17:38

问题


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?


回答1:


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.




回答2:


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)



回答3:


According to the docs, "limit_choices_to has no effect when used on a ManyToManyField with an intermediate table". By my reading, that means it has no effect at all, because ManyToManyFields use intermediate tables...

I haven't tried to make it work in the Admin site, but from your own views, you can create a form and override the queryset used to populate the list of choices:

form.fields["photos"].queryset = request.user.photo_set.all()


来源:https://stackoverflow.com/questions/345401/django-mtmfield-limit-choices-to-other-foreignkeyfield-on-same-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!