I am running Django 1.1 and cannot get the "limit_choices_to" option for my ManytoManyField to work.
I have two models:
class MemberPhoto(ImageModel):
title = models.CharField(_('title'), max_length=255, blank=True, null=True)
caption = models.CharField(_('caption'), max_length=255, blank=True, null=True)
date_added = models.DateTimeField(_('date added'), default=datetime.now, editable=False)
member = models.ForeignKey(User)
def __unicode__(self):
return u'%s (%s)' % (self.member.username, self.id)
and
class lock(models.Model):
user = models.ForeignKey(User, related_name="owner")
to_user = models.ForeignKey(User, related_name="to_user")
unlocked_photos = models.ManyToManyField(MemberPhoto, blank=True, null=True, limit_choices_to = {'member':'user'})
objects = locking_manager()
in the second model, i want to make sure in Django's admin that the only "unlocked_photos" ("MemberPhoto" objects) presented in the multiple select field are those who have a "member" value (a User object) the same as the "lock" object's "user" (also a User object).
I thought I had followed the Django docs on this, but it doesn't work. I get the following error:
TemplateSyntaxError
Caught an exception while rendering: invalid input syntax for integer: "user"
I've tried changing the "limit_choices_to" to things like:
limit_choices_to = {'member': user} --- Doesnt work
limit_choices_to = {'member__username':'kyle'} --- this DOES work but it's useless, i'm just manually specifying a username
How can I instead get the user from the current "lock" object and filter the MemberPhoto "member" property by that?
Thanks to anybody who can help.
Kyle
I found an answer that achieves exactly what I wanted at this link: Django MTMField: limit_choices_to = other_ForeignKeyField_on_same_model?, and I'm posting my working code here for anybody having the same problem. It seems from looking around that "limit_choices_to" may simply not be able to achieve what I wanted, and that customizing the form used by the admin is the way to go:
All you have to change is:
Hope this helps somebody!
To add to Kyle's answer,
Creating a custom form is the only way for to customize a many to many field in that way. But, like I discovered, that method only works if you are changing an instance of that model. (at least in Django 1.5)
This is because:
self.instance
will return Model object. (I know crazy concept) But if you are creating an instance of that model, since that model hasn't been created yet, theself.instance
will return aDoesNotExist
exception.A way around this issue is create two forms:
Then inside admin.py we would create a separate fieldset for our creation form:
Note that we had to override the get_form and get_fieldsets that if the obj is None (or in other words if the request is to add an instance of the model) it uses the MyModelCreationForm. This is the same method that the django developers use in django.contrib.auth.admin to get their custom UserCreation form and fieldsets. (Look in side the source code there for that example)
Finally the models would look something like this in model.py:
The only reason I included the models is so you could see the many to many field definition in class MyModel. It doesn't have to have null and blank set to True. Just remember if you don't you will have to either assign them a default value in the definition or set them in the save() function in the MyModelCreationForm.
Hope this helps! (If it's utterly wrong please correct me! I need to learn too.)
-Thanks