Django внешний ключ form.save () проблема - PullRequest
1 голос
/ 08 апреля 2020

Я новичок в Django и пытаюсь создать представление регистрации, используя форму с расширением модели User Model от django.contrib.auth.models и формы UserCreations, как показано ниже, однако произошла ошибка базы данных после отправки формы регистрации в сервер:

 ORA-01400: cannot insert NULL into (The foreign key)

Я думал, что ключ действительно будет сгенерирован автоматически. В чем проблема? Искренне ценю вашу помощь !! Ниже приведены виды:

 from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    from django.http import HttpResponse
    from django.shortcuts import render,redirect
    from django.contrib.auth import authenticate, login, logout

from .forms import signupform
def signup_view(request):
    if request.method =='POST':
        form = UserCreationForm(request.POST)
        s_form= signupform(request.POST)
        if form.is_valid()and s_form.is_valid():
            user =form.save()
            s_form.save()
            login(request,user)


        return redirect("../")
    else:
        form =UserCreationForm()
        s_form = signupform()

    return render(request,'signup.html',{'form':form,'s_form': s_form})

Вот формы

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


class signupform(forms.ModelForm):
    error_messages = {
        'password_mismatch': ("The two password fields didn't match."),
    }
    F_name = forms.CharField(label=("First Name"))
    L_name = forms.CharField(label=("Last Name"))
    Date_of_birth = forms.DateField()
    email = forms.EmailField(widget=forms.TextInput(
        attrs={'type': 'email',
               'placeholder': ('E-mail address')}))
    phone = forms.CharField()

    class Meta:
        model = Profile
        fields = ("F_name", "L_name", "Date_of_birth", "email")

    def save(self, commit=True):
        user = super(signupform, self).save(commit=False)
        if commit:
            user.save()
        return user

Вот модели:

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
from django import forms
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    Date_of_birth = models.DateField(null=True, blank=True)
    F_name =models.CharField(max_length=50 )
    L_name =models.CharField(max_length=50 )
    email=models.EmailField(null=True, blank=True)
    phone=models.CharField(max_length=8 )

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

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        try:
            instance.profile.save()
        except ObjectDoesNotExist:
            Profile.objects.create(user=instance)

1 Ответ

0 голосов
/ 08 апреля 2020

Проблема здесь в том, что ваш Profile в s_form по-прежнему не ссылается на User объект. Хотя вы создаете объект с сигналами, это не приведет к обновлению Proile в s_form, поскольку это другой объект Python.

Я советую отбрасывать сигналы в модели Profile, тем более что сигналы используются слишком часто, и многие вызовы Django ORM (особенно массовые) все равно обходят сигналы. См., Например, этот пост .

Затем вы можете связать пользователя с профилем в вашем представлении:

from .forms import signupform

def signup_view(request):
    if request.method =='POST':
        form = UserCreationForm(request.POST)
        s_form= signupform(request.POST)
        if form.is_valid()and s_form.is_valid():
            user =form.save()
            <b>s_form.instance.user = user</b>
            s_form.save()
            login(request,user)

Таким образом, модель Profile выглядит следующим образом:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    Date_of_birth = models.DateField(null=True, blank=True)
    F_name =models.CharField(max_length=50)
    L_name =models.CharField(max_length=50)
    email=models.EmailField(null=True, blank=True)
    phone=models.CharField(max_length=8)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...