Django:无法创建与一个普通模型具有一对一关系的多个模型对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django:无法创建与一个普通模型具有一对一关系的多个模型对象相关的知识,希望对你有一定的参考价值。

我有两个模型,用模型和用户之间的auth.models.User关系扩展django的one-to-one。我想使用表单创建这两个中的任何一个的对象。

两个型号是:

class Worker(models.Model):
    address = models.CharField(max_length=400)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

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

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

class Employer(models.Model):
    address = models.CharField(max_length=400)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

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

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

我有一个创建者视图功能:

def worker_sign_up(request):
    if request.method == 'POST':
        form = WorkerSignUpForm(request.POST)

        if form.is_valid():
            user = form.save(commit=False)
            user.employer = None
            user.worker = Worker()
            user.worker.address= form.cleaned_data.get('address')
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return redirect('home')
    else:
        form = WorkerSignUpForm()
    return render(request, 'registration/workersignup.html', {'form': form})


我期望在我的数据库中有一个user和一个worker,但它创建了WorkerEmployer对象。

附:我的表格类是:

class WorkerSignUpForm(UserCreationForm):
    address = forms.CharField(max_length=400)

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

答案

这是因为您正在关联Employer对象并保存User。而不是使用user.save(),使用user.worker.save()。这不会为Employer创建任何对象。

#views.py
def worker_sign_up(request):
    if request.method == 'POST':
        form = WorkerSignUpForm(request.POST)

        if form.is_valid():
            user = form.save()  #save the user
            user.worker = Collector()  # not sure why you need this
            user.worker.address= form.cleaned_data.get('address')

            user.worker.save()  # this will create an object for Worker only

            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return redirect('home')
    else:
        form = WorkerSignUpForm()
    return render(request, 'registration/workersignup.html', {'form': form})

此外,您需要将OneToOne字段设为可选字段。

# models.py
class Worker(models.Model):
    address = models.CharField(max_length=400)
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True
)


class Employer(models.Model):
    address = models.CharField(max_length=400)
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True
)

以上是关于Django:无法创建与一个普通模型具有一对一关系的多个模型对象的主要内容,如果未能解决你的问题,请参考以下文章

Django - 以一对多关系更改相关对象的值

Django:是否可以通过模型的PK将模型的FK链接到一对多关系?

关于自定义用户模型的 Django 最佳实践

Rails 尝试访问模型中的参数

MySQL 无法添加外键约束

Django 模型层之多表操作