Собираетесь ли вы позволить своему пользователю получить доступ к этой форме через сайт администратора?
Если это так, то простейшим решением для объединения двух форм (Пользователь и Ученик) будет использование встроенной модели вСайт администратора.
Решение 1 (самое простое - используйте сайт администратора, в качестве документа здесь ):
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from testapp.myauth.models import Student
from testapp.myauth.forms import UserForm
class StudentInline(admin.StackedInline):
model = Student
class MyUserAdmin(UserAdmin):
inlines = [
StudentInline,
]
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
Теперь, если вы этого не сделаетекак это решение, потому что оно не выглядит красиво, или вы не используете сайт администратора, вы можете сделать это сложным способом и без проблем объединить 2 формы (вы не увидите, что это 2 разные формы).Этот метод был получен из этого большого фрагмента .
Решение 2 (более продвинутый метод - бесшовная комбинация форм):
моделей.py
class Student(models.Model):
user = models.OneToOneField(User, unique=True)
address = models.CharField(max_length=10)
# Create student instance on access - very useful if you plan to always have a Student obj associated with a User object anyway
User.student = property(lambda u: Student.objects.get_or_create(user=u)[0])
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm
from testapp.myauth.models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
class UserForm(UserChangeForm):
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
student_kwargs = kwargs.copy()
if kwargs.has_key('instance'):
self.student = kwargs['instance'].student
student_kwargs['instance'] = self.student
self.student_form = StudentForm(*args, **student_kwargs)
self.fields.update(self.student_form.fields)
self.initial.update(self.student_form.initial)
# define fields order if needed
self.fields.keyOrder = (
'last_name',
'first_name',
# etc
'address',
)
def clean(self):
cleaned_data = super(UserForm, self).clean()
self.errors.update(self.student_form.errors)
return cleaned_data
def save(self, commit=True):
self.student_form.save(commit)
return super(UserForm, self).save(commit)
Так что я сделал здесь, чтобы создать экземпляр StudentForm внутри UserForm и объединить их полясоответственно.
Мое единственное предложение для вас состоит в том, чтобы рассмотреть вопрос о переименовании модели вашего профиля в нечто более общее, а не в Student (например, будет работать UserProfile), поскольку вы никогда не узнаете, если в будущем у вас могут появиться другие типы пользователей.другие студенты (например, учитель).