I'm making a Django app with custom users. I've outlined the key components of my problem below, missing code is denoted by '...'. My custom user model has a foreign key relationship as follows:
class MyCustomUser(models.AbstractBaseUser, models.PermissionsMixin)
...
location = models.ForeignKey(Location)
class Location(models.Model)
name = models.CharField(max_length=50, blank=True, null=True)
I've written a custom user form that includes this field as follows:
class MyCustomUserCreationForm(models.ModelForm)
...
location = forms.ModelChoiceField(Location.objects.all())
This all appears to be working correctly, however, there is no plus button to the right of the select field for location. I want to be able to add a location when I create a user, in the same way that you can add polls when creating choices in the Django tutorial. According to this question, I might not see the green plus if I don't have permission to change the model, but I am logged in as a superuser with all permissions. Any idea what I'm doing wrong?
You need to set a RelatedFieldWidgetWrapper
wrapper in your model form:
The RelatedFieldWidgetWrapper (found in django.contrib.admin.widgets) is used in the Admin pages to include the capability on a Foreign Key control to add a new related record. (In English: puts the little green plus sign to the right of the control.)
class MyCustomUserCreationForm(models.ModelForm)
...
location = forms.ModelChoiceField(queryset=Location.objects.all())
def __init__(self, *args, **kwargs):
super(MyCustomUserCreationForm, self).__init__(*args, **kwargs)
rel = ManyToOneRel(self.instance.location.model, 'id')
self.fields['location'].widget = RelatedFieldWidgetWrapper(self.fields['location'].widget, rel, self.admin_site)
I could make a mistake in the example code, so see these posts and examples:
I have created method based on the answers above:
def add_related_field_wrapper(form, col_name):
rel_model = form.Meta.model
rel = rel_model._meta.get_field(col_name).rel
form.fields[col_name].widget =
RelatedFieldWidgetWrapper(form.fields[col_name].widget, rel,
admin.site, can_add_related=True, can_change_related=True)
And then calling this method from my form:
class FeatureForm(forms.ModelForm):
offer = forms.ModelChoiceField(queryset=Offer.objects.all(), required=False)
package = forms.ModelChoiceField(queryset=Package.objects.all(), required=False)
def __init__(self, *args, **kwargs):
super(FeatureForm, self).__init__(*args, **kwargs)
add_related_field_wrapper(self, 'offer')
add_related_field_wrapper(self, 'package')
That works fine on Django 1.8.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With