2017-08-16 14 views
2

私は、サービス(顧客)を使用している人か、サービス(worker)を提供している人のどちらかにサインアップできるサイトを持っています。私は、それぞれを表すためにmodels.pyに2つのプロファイルを作成しました。彼らは今のところほとんどの部分で非常に似ています。あなたがそれらに行くとき、両方のフォームが適切に表示され、あなたが顧客としてサインアップして、すべてをスムーズに進めると、新しい顧客が "顧客プロフィール"にhttp://127.0.0.1:8000/admin/で表示されます。あなたは労働者として登録しようとした場合でも、次のエラーが表示されますDjangoモデルを拡張する際の問題

Exception Type: RelatedObjectDoesNotExist 
Exception Value:  
User has no workerprofile. 

私はcustomerprofileを使用して、私はworkerprofileそれを使用する場合には、正常に動作下にあなたがコードで表示されますようので、私はこのことを理解していませんクラッシュします。

Views.py:

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

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

forms.py:

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',) 

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_worker_profile(sender, instance, created, **kwargs): 
    if created: 
     CustomerProfile.objects.create(user=instance) 

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

私は問題が何であるかを理解していません。

答えて

1

両方のモデルのシグナルハンドラメソッド名は同じです。実際にはメソッドを再定義しているため、2番目のメソッドセットだけが呼び出されます。 CustomerProfileハンドラーの名前をcreate_customer_profilesave_customer_profileに変更します。

+0

ありがとうあなたはまだ顧客と労働者のフィールドを追加していませんが、それらがすべて 'birth_date'と 'university'を共有している場合は、これにアプローチするより良い方法がありますか? –

+0

@ JustinO'Brien繰り返しの量を減らしたい場合は、[抽象基本モデル](https://docs.djangoproject.com/en/1.11/topics/db/models/#abstract-base)を使用することができます。 -classes)、そこにすべての共有フィールドを含めます。これにより、まったく同じデータベース構造になりますが、コードはDRYの原則に準拠します。 – Selcuk

+1

ありがとう@selcuk、私はそれを感謝します –

関連する問題