所以我想知道Django 1.7.1中是否有可能像reverse Tabular Inline
这样做:
现在我有:
型号:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
我希望我的内联类似:
class UserInline(admin.TabularInline):
model = get_user_model()
class UserProfileAdmin(admin.ModelAdmin):
inlines = [
UserInline,
]
但我得到<class 'users.admin.UserInline'>: (admin.E202) 'auth.User' has no ForeignKey to 'users.UserProfile'.
我真的需要只使用UserProfile来创建/编辑新用户,而不是像内联文档所建议的那样。
任何人都知道如何实现这一目标?
答案 0 :(得分:1)
有几种方法可以在Django中扩展用户模型,看起来你选择了错误的用例。
尝试使用继承来扩展内置用户模型。
class UserWithProfile(AbstractBaseUser):
...
date_of_birth = models.DateField()
relationship_status = models.IntegerField(choices=RS)
height = models.FloatField()
...
REQUIRED_FIELDS = ['date_of_birth', 'height']
在settings.py:
AUTH_USER_MODEL = 'myapp.UserWithProfile'
答案 1 :(得分:0)
我发现了一种更简单的方法,通过创建自己的自定义模型,我可以实现这一点:
class GirlModelForm(forms.ModelForm):
username = forms.CharField(
label=_('username'), max_length=30,
help_text=_(
'Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.'
),
validators=[
validators.RegexValidator(
r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid'
)
])
first_name = forms.CharField(label=_('first name'), max_length=30)
last_name = forms.CharField(label=_('last name'), max_length=30)
email = forms.EmailField(label=_('email address'))
# The attribute required must be False because of the clean() workaround
user = forms.ModelChoiceField(
queryset=get_user_model().objects.all(), required=False
)
class Meta:
model = Girl
# fields = [
# 'degree', 'extra_field'
# ]
def __init__(self, *args, **kwargs):
if not kwargs.get('initial'):
kwargs['initial'] = {}
if kwargs.get('instance'):
kwargs['initial'].update({
'username': kwargs['instance'].user.username,
'first_name': kwargs['instance'].user.first_name,
'last_name': kwargs['instance'].user.last_name,
'email': kwargs['instance'].user.email,
})
super(GirlModelForm, self).__init__(*args, **kwargs)
def clean(self):
"""
This is a nasty workaround and it exists so that we can create/edit
the user directly in the Userprofiles. The motive is referenced here
http://stackoverflow.com/q/27235143/977622 and basically the idea is
to make the built in user NOT REQUIRED and GET or CREATE the user
object and create a new attribute in the cleaned_data with the user
object
"""
cleaned_data = super(GirlModelForm, self).clean()
user, created = get_user_model().objects.get_or_create(
email=cleaned_data['email'],
defaults={
'first_name': cleaned_data['first_name'],
'last_name': cleaned_data['last_name'],
'username': cleaned_data['username'],
}
)
if not created:
# If the user exists update it
user.first_name = cleaned_data['first_name']
user.last_name = cleaned_data['last_name']
user.username = cleaned_data['username']
user.save()
cleaned_data['user'] = user
也许有更好的方法可以做到这一点,但这是我能够做的,而无需重做我的模型