2016-05-17 2 views
3

sein kann Wir benötigen zwei separate Formulare für zwei verschiedene Benutzertypen. Nennen Sie sie Client und Provider. Der Client wäre der Elternteil, der Basisbenutzer, während der Provider eine Art von Erweiterung ist. Zu jedem Zeitpunkt kann ein Kunde auch ein Anbieter werden, während er als Kunde den Status und die Informationen behält. Ein Provider hat also sowohl Berechtigungen als Client als auch als Provider.Django - Erstellen von zwei Benutzertypen, wobei ein Typ sowohl

Ich bin neu in Django. Wir versuchen lediglich, einen beliebigen Benutzertyp zu registrieren, haben aber eine Eins-zu-Eins-Beziehung zwischen Provider- und Client-Tabellen, wenn sich ein Benutzer sofort als Provider registriert.

Das Problem, das wir haben, ist im Adapter, wir denken. Ein Provider registriert sich zwar gut, landet aber in der Tabelle users_user ohne Eintrag in der generierten Tabelle users_provider. Ist es die Art, wie wir diese beiden Entitäten in der Datenbank speichern oder in Beziehung setzen wollen, oder etwas anderes?

Wir versuchen, Allauthen für Authentifizierung und Registrierung zu verwenden.

Unser Code:

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 

unsere 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() 

schließlich unsere 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 

Jede Hilfe oder Tipps würden sehr geschätzt werden. Wenn ich etwas vergessen habe, lass es mich wissen. Ich bin mir nicht sicher, ob das Problem im Modell selbst, in der Art, wie wir das Formular darstellen, oder im Adapter liegt. So wie es aussieht, spielt es keine Rolle, welche Form wir verwenden, es wird immer gespeichert, da die Basis-Benutzertabelle (unser Client) und die Provider-Tabelle niemals Informationen gespeichert werden.

Antwort

2

Mit Djangos neuem benutzerdefinierten Benutzermodell kann nur ein Benutzermodell als settings.AUTH_USER_MODEL festgelegt werden. In Ihrem Beispiel können Sie dies auf Ihr Modell User einstellen.

Erstellen Sie dann für die optionalen Anbieterdaten ein separates Modell, das von OneToOneField aus Ihrem Modell User referenziert wird.

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

class Provider(models.Model): 
    ... 

Dies ist der einfachste Weg, mit mehreren Benutzertypen in Django, die AUTH_USER_MODEL Einschränkung gegeben zu arbeiten.

Es ist auch am besten, nur abstrakte Modelle zu unterklassifizieren, andernfalls erhalten Sie eine mehrfache Vererbung, die zu verborgenen implizierten JOINs führt, die die Leistung beeinträchtigen.

Schließlich können Sie das Objekt Provider in der benutzerdefinierten Methode form.is_valid() Methode erstellen und zuweisen user.provider = provider.

Verwandte Themen