2014-12-01 103 views
0

,所以我在想,如果它可能在Django 1.7.1像做一個reverse Tabular Inline例如:Django管理反向TabularInline

現在我得:

型號:

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來創建/編輯新用戶,而不是像內聯文檔所建議的那樣。

任何人都有一個想法,我可以如何實現這一目標?

回答

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' 
+0

感謝您的答案。我正在考慮使用AbstractUser並設置AUTH_USER_MODEL ='mynewuser',而我相信它應該是一樣的權利? – psychok7 2014-12-02 11:11:07

+0

是的,'AbstractUser'對於強制方法/屬性有一些簡單的默認值。 – 2014-12-02 11:51:22

0

我發現了一個更簡單的方法,在這裏我能夠通過創建自己的自定義的ModelForm得到這個工作:

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'^[\[email protected]+-]+$', _('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 

也許有一個更好的方法來做到這一點,但這是我能夠做到而不重做我的模型