Представление полей из двух моделей на одной странице просмотра
Вы должны расширить класс django.views.generic.View и переопределить методы get (request) и post (request).
Вот как я это сделал.
Я использую Джанго 1.11 .
Вот так выглядит моя форма (состоящая из двух форм):
Мой Просмотр класса, который отображает две мои формы:
from django.views.generic import View
class UserRegistrationView(View):
# Here I say which classes i'm gonna use
# (It's not mandatory, it's just that I find it easier)
user_form_class = UserForm
profile_form_class = ProfileForm
template_name = 'user/register.html'
def get(self, request):
if request.user.is_authenticated():
return render(request, 'user/already_logged_in.html')
# Here I make instances of my form classes and pass them None
# which tells them that there is no additional data to display (errors, for example)
user_form = self.user_form_class(None)
profile_form = self.profile_form_class(None)
# and then just pass them to my template
return render(request, self.template_name, {'user_form': user_form, 'profile_form': profile_form})
def post(self, request):
# Here I also make instances of my form classes but this time I fill
# them up with data from POST request
user_form = self.user_form_class(request.POST)
profile_form = self.profile_form_class(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save(commit=False)
user_profile = profile_form.save(commit=False)
# form.cleaned_data is a dictionary which contains data validated
# by fields constraints (Say we have a field which is a number. The cleaning here would
# be to just convert a string which came from the browser to an integer.)
username = user_form.cleaned_data['username']
password = user_form.cleaned_data['password']
# This will be clarified later
# You can save each object individually if they're not connected, as mines are (see class UserProfile below)
user.set_password(password)
user.userprofile = user_profile
user.save()
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('user:private_profile')
# else: # form not valid - each form will contain errors in form.errors
return render(request, self.template_name, {
'user_form': user_form,
'profile_form': profile_form
})
У меня есть модели User
и UserProfile
.
User
равно django.contrib.auth.models.User
и UserProfile
выглядит следующим образом:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
friends = models.ManyToManyField('self', null=True, blank=True)
address = models.CharField(max_length=100, default='Some address 42')
def get_absolute_url(self):
return reverse('user:public_profile', kwargs={'pk': self.pk})
def __str__(self):
return 'username: ' + self.user.username + '; address: ' + self.address
@receiver(post_save, sender=User) # see Clarification 1 below
def create_user_profile(sender, instance, created, **kwargs):
if created: # See Clarification 2 below
UserProfile.objects.create(user=instance, address=instance.userprofile.address)
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, **kwargs):
instance.userprofile.save()
Уточнение 1: @receiver (post_save, sender = User)
- при сохранении пользователя (я где-то написал user.save () (пользователь является экземпляром класса User)) UserProfile также будет сохранен.
Пояснение 2: , если создано: (уточнение из класса View)
Если пользователя СОЗДАЮТ, создайте UserProfile
где пользователь = пользовательский экземпляр, который был только что отправлен через пользовательскую форму
адрес собирается из ProfileForm и добавляется в пользовательский экземпляр ранее
вызов user.save ()
У меня есть две формы:
UserForm:
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(render_value=True), required=True)
password_confirmation = forms.CharField(widget=forms.PasswordInput(render_value=True), required=True)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
class Meta:
model = User
fields = ('email', 'username', 'first_name', 'last_name', 'password', 'password_confirmation')
def clean(self):
cleaned_data = super(UserForm, self).clean()
password = cleaned_data.get("password")
password_confirmation = cleaned_data.get("password_confirmation")
if password != password_confirmation:
self.fields['password'].widget = forms.PasswordInput()
self.fields['password_confirmation'].widget = forms.PasswordInput()
self.add_error('password', "Must match with Password confirmation")
self.add_error('password_confirmation', "Must match with Password")
raise forms.ValidationError(
"Password and Password confirmation do not match"
)
ProfileForm:
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('address',)
Я надеюсь, что я хорошо понял ваш вопрос и что это поможет вам (и другим). :)