2016-05-17 5 views
3

2種類の異なるタイプの2つのフォームが必要です。それらをClientProviderと呼んでください。クライアントは親のベースユーザになりますが、プロバイダは一種の拡張です。いつでも、クライアントはステータスと情報をクライアントとして維持しながら、プロバイダになることもできます。したがって、プロバイダには、クライアントとプロバイダの両方の権限があります。Django - 2つのユーザータイプを作成します.1つのタイプは両方とも可能です。

私はDjangoを初めて使いました。私たちがやろうとしているのは、いずれかのユーザータイプを登録するだけですが、ユーザーがプロバイダーとしてすぐ登録すると、プロバイダーテーブルとクライアントテーブルの間に1対1の関係があります。

アダプターに問題があります。と思います。プロバイダは正常に登録しますが、users_providerテーブルにエントリがないusers_userテーブルに終わります。それは、データベース内のこれらの2つのエンティティを保存し関連付ける方法ですか?

認証と登録にallauthを利用しようとしています。

当社コード:

models.py:

class User(AbstractUser): 
    name = models.CharField(_('Name of User'), blank=True, max_length=255) 
    def __str__(self): 
     return self.username 

    def get_absolute_url(self): 
     return reverse('users:detail', kwargs={'username': self.username}) 

    SEX = (
     ("M","MALE"), 
     ("F","FEMALE"), 
    ) 

    birthdate = models.DateField(_('Birth Date'), default=django.utils.timezone.now, blank=False) 
    sex = models.CharField(_('Sex'), choices=SEX, max_length=1, default="M") 
    isProvider = models.BooleanField(_('Provider'), default=False) 


#Using User, not models.Model 
class Provider(User): 

    HAS_BUSINESS = (
     ('YES','YES'), 
     ('NO','NO'), 
    ) 

#Resolving asociation 1:1 to User 
#NOTE: AUTH_USER_MODEL = users.User in setting 
    owner = models.OneToOneField(settings.AUTH_USER_MODEL) 
    has_business = models.CharField(_('Do you have your own business?'),max_length=2, choices=HAS_BUSINESS, default='NO') 
    isProvider = True 

当社forms.py

class ProviderForm(SignupForm,ModelForm): 

    name = forms.CharField(label='Name', strip=True, max_length=50) 
    lastname = forms.CharField(label='Last Name', strip=True, max_length=50) 
    Provider.isProvider = True 

    class Meta: 
     model = Provider 
     fields = '__all__' 
     exclude = GENERAL_EXCLUSIONS + [ 
     'owner', 
     ] 

class ClientForm(SignupForm,ModelForm): 

    name = forms.CharField(label='Name', strip=True, max_length=50) 
    lastname = forms.CharField(label='Last Name', strip=True, max_length=50) 

    class Meta: 
     model = User 
     fields = "__all__" 
     exclude = GENERAL_EXCLUSIONS 

    def is_active(self): 
     return False 

    def __init__(self, *args, **kwargs): 
     super(ClientForm, self).__init__(*args, **kwargs) 

views.py:最後に

class ProviderRegisterView(SignupView): 
    template_name = 'account/form_provider.html' 
    form_class = ProviderForm 
    redirect_field_name = 'next' 
    view_name = 'registerprovider' 
    success_url = None 

    def get_context_data(self, **kwargs): 
     ret = super(ProviderRegisterView, self).get_context_data(**kwargs) 
     ret.update(self.kwargs) 
     return ret 

registerprovider = ProviderRegisterView.as_view() 


#View para el formulario de registro de usuarios clientes 
class ClientRegisterView(SignupView): 

    template_name = 'account/form_client.html' 
    form_class = ClientForm 
    redirect_field_name = 'next' 
    view_name = 'registerclient' 
    success_url = None 

    def get_context_data(self, **kwargs): 
     ret = super(ClienteRegisterView, self).get_context_data(**kwargs) 
     ret.update(self.kwargs) 
     return ret 

registerclient = ClienteRegisterView.as_view() 

、私たちのadapter.py :

#Per allauth documentation, settings changed: 
#ACCOUNT_ADAPTER = 'projectname.users.adapters.RegisterUserAdapter' 

class RegisterUserAdapter(DefaultAccountAdapter): 
    def save_user(self, request, user, form, commit=True): 
     data = form.cleaned_data 
     user.first_name = data['name'] 
     user.last_name = data['lastname'] 
     #Saving Client info 
     user.sex = data['sex'] 
     user.birthdate = data['birthdate'] 
     #Normal allauth saves 
     user.username = data['username'] 
     user.email = data['email'] 
     if user.isProvider: 
      p = Provider() 
      p.owner = user 
      p.has_business = data['has_business'] 
     if 'password1' in data: 
      user.set_password(data['password1']) 
     else: 
      user.set_unusable_password() 
     self.populate_username(request, user) 
     if commit: 
      #Save user 
      user.save() 
      #If it's also a Provider, save the Provider 
      if user.isProvider: 
       p.save() 
     return user 

何か助けやヒントをいただければ幸いです。私が何かを残したら、私に知らせてください。モデル自体に問題があるかどうか、私たちがフォームを表現する方法、またはアダプタがわからない。どのような形式で使用しても問題ありません。基本Userテーブル(Client)として常に保存され、Providerテーブルには情報が保存されません。

答えて

2

Djangoの新しいカスタムユーザーモデルでは、1つのユーザーモデルしかsettings.AUTH_USER_MODELとして設定できません。あなたの例では、Userモデルに設定することができます。

次に、オプションのプロバイダデータについては、UserモデルのOneToOneFieldによって参照される個別のモデルを作成します。

class User(AbstractUser): 
    ... 
    provider = models.OneToOneField(Provider, null=True) 

class Provider(models.Model): 
    ... 

これはAUTH_USER_MODEL制約与えられたジャンゴで複数のユーザーが、で動作する最も簡単な方法です。

また、抽象モデルをサブクラス化することをお勧めします。そうしないと、暗黙的なJOINが発生し、パフォーマンスが低下するマルチテーブル継承が発生します。

最後に、カスタムフォームのform.is_valid()メソッドでProviderオブジェクトを作成し、user.provider = providerを割り当てることができます。

関連する問題