问题扩展django用户模型

时间:2017-08-17 12:49:20

标签: django django-models django-forms

我有一个网站,用户应该可以注册为"工作人员"或者"客户",一种超级模型类型的网站。我创建了两个模型WorkerProfileCustomerProfile以及两个表单,但每次我提交客户或工作表单时,新用户都会被置于客户个人资料和工作人员个人资料中#39;在http://127.0.0.1:8000/admin/的数据库中,如何防止这种情况发生?

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 %}

2 个答案:

答案 0 :(得分: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)
    ...

答案 1 :(得分:0)

这是正常的:

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

如果你在两个模型中调用它,那么在save()期间,它将创建两个。

我建议你修改你的模型。为什么不创建模型&#39; Profil&#39;并放置一个布尔字段&#39; is_customer&#39;是/否?