Extendí el modelo de usuario de Django y agregué mis propios campos, y actualmente estoy trabajando para completar estos campos durante el registro. El formulario parece estar funcionando correctamente, con todo excepto el guardado.

Usé esto para ayudarme .

Aquí está la extensión del modelo de usuario:

class StudentProfile(models.Model):
    user = models.OneToOneField(User, null = True, related_name='user', on_delete=models.CASCADE)
    teacher = models.BooleanField(default = False)
    school = models.CharField(max_length = 50)

def create_StudentProfile(sender, **kwargs):
    if kwargs['created']:
        user_profile = StudentProfile.objects.create(user = kwargs['instance'])


post_save.connect(create_StudentProfile, sender = User)

Aquí está mi formulario:

class StudentRegistrationForm(UserCreationForm):
    email = forms.EmailField(required = True)
    school = forms.CharField(required = True)

    def __init__(self, *args, **kwargs):
        super(StudentRegistrationForm, self).__init__(*args, **kwargs)
        self.fields['username'].help_text = ''
        self.fields['password2'].help_text = ''


    class Meta:
        model = User

        fields = (
            'username',
            'first_name',
            'last_name',
            'email',
            'school',
            'password1',
            'password2'            
        )

    def save(self, commit = True):
        user = super(StudentRegistrationForm, self).save(commit = False)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']


        student_profile = StudentProfile(user = user, school = self.cleaned_data['school'])

        if commit:
            user.save()
            student_profile.save()

        return user, student_profile

Aquí está mi punto de vista:

def registration(request):
    if request.method == 'POST':
        form = StudentRegistrationForm(request.POST)
        if form.is_valid():
            user, user_profile = form.save(commit = False)
            form.save()
            return render(request, 'accounts/home.html')
        else:
            args = {'form': form}
            return render(request, 'accounts/reg_form.html', args)

    else:
        form = StudentRegistrationForm()

        args = {'form': form}
        return render(request, 'accounts/reg_form.html', args)

Aquí está mi rastreo:

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)

The above exception (NOT NULL constraint failed: userprofile_studentprofile.user_id) was the direct cause of the following exception:

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/wtreston/GDrive/LesRev/lesssonreview/userprofile/views.py" in registration
  13.             form.save()

File "/Users/wtreston/GDrive/LesRev/lesssonreview/userprofile/forms.py" in save
  41.             student_profile.save()

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in save
  796.                        force_update=force_update, update_fields=update_fields)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  824.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
  908.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert
  947.                                using=using, raw=raw)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/query.py" in _insert
  1045.         return query.get_compiler(using=using).execute_sql(return_id)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1054.                 cursor.execute(sql, params)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  94.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/six.py" in reraise
  685.             raise value.with_traceback(tb)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /users/
Exception Value: NOT NULL constraint failed: userprofile_studentprofile.user_id

¡Gracias!

0
wtreston 12 jun. 2017 a las 14:35

3 respuestas

La mejor respuesta

Debe crear un usuario utilizando el modelo User y luego debe pasar este usuario a StudentProfile porque es un campo onetoone para usted StudentProfile.

def save(self, request):
        form = StudentRegistrationForm(request.POST)
        user = User.objects.create(first_name=form.cleaned_data['first_name'],
                            last_name=form.cleaned_data['last_name'],
                            email=form.cleaned_data['email'],
                            username=form.cleaned_data['username'])
        user_profile = StudentProfile.objects.create(user=user,
                                                teacher=form.cleaned_data['teacher'],
                                                school=form.cleaned_data['school'])


        return user, student_profile
1
Arpit Solanki 12 jun. 2017 a las 11:53

Hay una serie de problemas aquí.

El problema inmediato es que está creando el UserProfile en dos lugares. Ha registrado un manejador de señal - create_StudentProfile - que crea uno automáticamente cuando se crea el Usuario; pero también está creando uno nuevo en el método save del formulario.

Debería considerar si realmente necesita ese controlador de señal. Si siempre va a crear el Usuario a través de este formulario, entonces ese controlador es innecesario.

Si decide que necesita la señal, deberá rehacer su método de guardado para tenerlo en cuenta. Algo como:

def save(self, commit=True):
    user = super(StudentRegistrationForm, self).save(commit = False)
    if commit:
        user.save()
        profile = user.userprofile
    else:
        profile = UserProfile(user=user)

    profile.school = self.cleaned_data['school']

    if commit:
        profile.save()

    return user, student_profile

Notarás que no es necesario configurar el correo electrónico y el nombre, ya que estos se realizan mediante el formulario que ya está en la súper llamada.

El segundo problema es que está llamando al método de guardar dos veces desde su punto de vista. No hagas eso.

    if form.is_valid():
        user, user_profile = form.save()
        return render(request, 'accounts/home.html')
0
Daniel Roseman 12 jun. 2017 a las 12:13

Parece que el objeto de uso no se está guardando, por lo que puede almacenar su modelo de referencia StudentProfile.

0
AR7 12 jun. 2017 a las 11:50