HenryM
HenryM

Reputation: 5793

Django convert string into model for form

I'm trying to write a simple reusable Django app which links into the User model but since this can be replaced I need to link it into AUTH_USER_MODEL.

This is fine within models but I have a formset based on the User so I need a form which I'm trying to populate as follows:

from django.forms import ModelForm
from django.forms.models import inlineformset_factory

from optin.models import UserOptin
from django.conf import settings
#from django.contrib.auth.models import User
USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', None) or \
             'auth.User'

class UserForm(ModelForm):
    class Meta:
        model = USER_MODEL
        fields = '__all__'


class UserOptinForm(ModelForm):
    class Meta:
        model = UserOptin
        fields = '__all__'

UserOptinFormSet = inlineformset_factory(USER_MODEL, UserOptin,
form=UserOptinForm, extra=0)

This generates an error:

AttributeError: 'unicode' object has no attribute '_meta'

This is because USER_MODEL is a string. How do I convert it into the actual model?

Upvotes: 0

Views: 704

Answers (1)

Lemayzeur
Lemayzeur

Reputation: 8525

You can use eval() function, all expressions argument parsed inside will be evaluated as a Python expression More info can be found here

USER_MODEL = eval(getattr(settings, 'AUTH_USER_MODEL', None) or 'auth.User') 
# The fallback will raise an Error here

I suggest that you import User from django.contrib.auth.models Because, if AUTH_USER_MODEL is not defined, the fallback will be auth.User, it will raise NameError no module name auth, so you may use the following

from django.contrib.auth.models import User
USER_MODEL = eval(getattr(settings, 'AUTH_USER_MODEL', None) or 'User')

Upvotes: 2

Related Questions