2017-08-17 15 views
1

私は、ユーザーがサイトのユーバーモデルタイプである "ワーカー"または "顧客"としてサインアップできるWebサイトを持っています。 WorkerProfileCustomerProfileの2つのモデルと2つのフォームを作成しましたが、カスタマーフォームまたは従業員フォームのいずれかを送信するたびに、新しいユーザーは顧客プロファイルとワーカープロファイルの両方にデータベースのhttp://127.0.0.1:8000/admin/を入れてしまいますハプニング?問題を拡張するdjangoユーザーモデル

models.py:

from django.db import models 
from django.contrib.auth.models import User 
from django.db.models.signals import post_save 
from django.dispatch import receiver 

class WorkerProfile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    university = models.CharField(max_length=30, blank=True) 
    birth_date = models.DateField(null=True, blank=True) 

    role = models.CharField(max_length = 10, default = 'USER') 


    def __str__(self): 
     return self.user.username 

@receiver(post_save, sender=User) 
def create_worker_profile(sender, instance, created, **kwargs): 
    if created: 
     WorkerProfile.objects.create(user=instance) 

@receiver(post_save, sender=User) 
def save_worker_profile(sender, instance, **kwargs): 
    instance.workerprofile.save() 







class CustomerProfile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    university = models.CharField(max_length=30, blank=True) 
    birth_date = models.DateField(null=True, blank=True) 

    role = models.CharField(max_length = 10, default = 'CUSTOMER') 
    needLaundryDone = models.BooleanField(default = False) 

    def __str__(self): 
     return self.user.username 

@receiver(post_save, sender=User) 
def create_customer_profile(sender, instance, created, **kwargs): 
    if created: 
     CustomerProfile.objects.create(user=instance) 

@receiver(post_save, sender=User) 
def save_customer_profile(sender, instance, **kwargs): 
    instance.customerprofile.save() 

forms.py:

from django import forms 
from django.contrib.auth.forms import UserCreationForm 
from django.contrib.auth.models import User 

class WorkerSignUpForm(UserCreationForm): 
    #birth_date and university fields need to be declared seperately because they are not apart of User: 
    birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD') 
    university = forms.CharField() 


    class Meta: 
     model = User 
     fields = ('username', 
        'email', 
        'first_name', 
        'last_name', 
        'birth_date', 
        'university', 
        'password1', 
        'password2',) 


class CustomerSignUpForm(UserCreationForm): 
    #birth_date and university fields need to be declared seperately because they are not apart of User: 
    birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD') 
    university = forms.CharField() 


    class Meta: 
     model = User 
     fields = ('username', 
        'email', 
        'first_name', 
        'last_name', 
        'birth_date', 
        'university', 
        'password1', 
        'password2',) 

views.py:

def signup(request): 
    if request.method == 'POST': 
     form_worker = WorkerSignUpForm(request.POST) 
     form_customer = CustomerSignUpForm(request.POST) 
     if form_worker.is_valid(): 
      user = form_worker.save() 
      user.refresh_from_db() # load the profile instance created by the signal 
      user.workerprofile.birth_date = form_worker.cleaned_data.get('birth_date') 
      user.workerprofile.university = form_worker.cleaned_data.get('university') 
      user.save() # explicitly save custom fields not in User model 
      raw_password = form_worker.cleaned_data.get('password1') 
      user = authenticate(username=user.username, password=raw_password) 
      login(request, user) # login user after signup 
      return redirect('home') 
     elif form_customer.is_valid(): 
      user = form_customer.save() 
      user.refresh_from_db() # load the profile instance created by the signal 
      user.customerprofile.birth_date = form_customer.cleaned_data.get('birth_date') 
      user.customerprofile.university = form_customer.cleaned_data.get('university') 
      user.save() # explicitly save custom fields not in User model 
      raw_password = form_customer.cleaned_data.get('password1') 
      user = authenticate(username=user.username, password=raw_password) 
      login(request, user) # login user after signup 
      return redirect('home') 
    else: 
     form_worker = WorkerSignUpForm(request.POST) 
     form_customer = CustomerSignUpForm(request.POST) 
    return render(request, 'core/signup.html', {'form_worker': form_worker,'form_customer': form_customer }) 

signup.html:

{% extends 'core/base.html' %} 

{% block head %} 
    <title> Sign Up</title> 
{% endblock %} 
{% block body %} 


    <h3>Sign Up As Worker</h3> 
    <form method="post"> 
    {% csrf_token %} 
    {{ form_worker.as_p }} 
    <button type="submit">Sign up</button> 
    </form> 

    <h3>Sign Up As Customer</h3> 
    <form method="post"> 
    {% csrf_token %} 
    {{ form_customer.as_p }} 
    <button type="submit">Sign up</button> 
    </form> 
{% endblock %} 

答えて

0

ここでは信号を使用しないでください。彼らはユーザーの保存時に起動し、それぞれ関連オブジェクトを作成します。

これらの信号を削除し、その代わりにビューで行う必要があります。各フォームのブロックis_validでは、必要な特定のオブジェクトのみを作成できます。

if form_worker.is_valid(): 
    user = form_worker.save() 
    worker = WorkerProfile(user=user) 
    worker.birth_date = form_worker.cleaned_data.get('birth_date') 
    worker.university = form_worker.cleaned_data.get('university') 
    worker.save() 
    raw_password = form_worker.cleaned_data.get('password1') 
    ... 
elif form_customer.is_valid(): 
    user = form_customer.save() 
    customer = CustomerProfile(user=user) 
    ... 
+0

私はDanielに同意し、信号を使用しません。 – GrandGTO

+0

@DanielRosemanあなたが言ったように私はビューを更新しました。コメントが長すぎるので、ここにhttps://jsfiddle.net/jkm74fv4/を入れてください。しかし、今では私が顧客としてサインアップしても、すべてが「ワーカー」プロファイルとして保存されていますか? –

+0

フォームをインスタンス化して区別するには、接頭辞を使用する必要があります。より詳しく見ると、私はあなたがなぜ2つのフォームを持っているのかを本当に理解できません。なぜ1つのフォーム、ワーカー/顧客のチェックボックスですか? –

0

これは正常です:

user = models.OneToOneField(User, on_delete=models.CASCADE) 

あなたは両方のモデルでこれを呼び出した場合、保存時のように、()、それは両方を作成します。

あなたの提案は、モデルを変更することです。なぜ、モデル 'Profil'を作成し、ブール値のフィールド 'is_customer'をTrue/Falseに設定するのはなぜですか?

+0

ボタンを押している顧客で、サービスを提供する人物(lookForServiceなどの顧客のブール値フィールド)を探していることを伝えてから、支払いなどを追加する必要があるというような機能を追加する予定です情報(労働者の支払いをどこに送金するか、そして顧客から支払いを受ける場所)。顧客/労働者のそれぞれが「Profile」のフィールドが常にnullまたは空の文字列に等しい(つまり、workerが 'lookingForService'フィールドを必要としない)特定のフィールドを持っていれば大丈夫でしょうか?労働者? –

+0

フィールドをNullまたはFalseのままにしておくと、問題はありません。つまり、基本的には、アプリケーションでユーザーがプロファイルのすべてのフィールドを入力しないことはまれではありません。 – GrandGTO

関連する問題