【问题标题】:Django admin reverse TabularInlineDjango 管理员反向 TabularInline
【发布时间】:2014-12-01 18:50:00
【问题描述】:

所以我想知道它是否可以在 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 来创建/编辑新用户,而不是像内联文档建议的那样。

有人知道我如何实现这一目标吗?

【问题讨论】:

    标签: django django-admin


    【解决方案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'
    

    【讨论】:

    • 感谢您的回答。我正在考虑使用 AbstractUser 并设置 AUTH_USER_MODEL = 'mynewuser' 但我相信它应该差不多吧?
    • 是的,AbstractUser 对强制方法/属性有一些简单的默认值。
    【解决方案2】:

    我找到了一个更简单的方法,我可以通过创建自己的自定义模型表单来实现它:

    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
    

    也许有更好的方法来做到这一点,但这是我无需重做模型就能做到的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 2011-08-04
      • 2011-11-03
      • 2017-05-13
      • 1970-01-01
      相关资源
      最近更新 更多