Y
Y
Yura Khlyan2016-07-07 13:12:44
Django
Yura Khlyan, 2016-07-07 13:12:44

How to keep two models on one page?

Good day.
I have two models: Userand CustomerProfile. They are related like OneToOneField. I need to create both of them on the same page. Here are code examples:
views.py:

class UserCreateView(generic.CreateView):
    template_name = 'dashboard/users/user_create.html'
    model = User

    form_class = forms.NewCustomerForm
    profile_form = forms.CustomerProfileForm

    def get_initial(self):
        initial = super(UserCreateView, self).get_initial()
        initial = initial.copy()
        initial['username'] = generate_username()
        return initial

    def get(self, request, *args, **kwargs):
        request.GET = request.GET.copy()
        if request.META['HTTP_REFERER'].endswith('orders/add/'):
            request.GET['HTTP_REFERER'] = 'order_create'
        return super(
            UserCreateView, self).get(request, *args, **kwargs)

    def get_success_url(self, request):
        if request.GET.get('HTTP_REFERER') == 'order_create':
            return reverse('dashboard:order-create')
        return reverse('dashboard:users-index')

    def get_context_data(self, *args, **kwargs):
        ctx = super(UserCreateView, self).get_context_data(
            *args, **kwargs
        )
        ctx['cancel_url'] = reverse('dashboard:users-index')
        ctx['profile_form'] = self.profile_form
        return ctx

    def form_valid(self, form, request):
        self.object = form.save()
        return HttpResponseRedirect(self.get_success_url(request))

    def post(self, request, *args, **kwargs):
        self.object = None
        form = self.get_form()
        if form.is_valid():
            post_data = self.form_valid(form, request)
        else:
            post_data = self.form_invalid(form)

        profile_form = self.profile_form(
            **self.get_profile_form_kwargs())

        # profile_form.instance.user = self.object
        import pdb; pdb.set_trace() # debug yskhlyan
        if profile_form.is_valid():
            customer_profile = profile_form.save()
            customer_profile.save()
            post_data = self.form_valid(form, request)
        else:
            post_data = self.render_to_response(
                self.get_context_data(form=form, profile_form=profile_form))

        return post_data

    def get_profile_form_kwargs(self):
        kwargs = {
            'initial': self.get_profile_initial(),
            'prefix': self.get_prefix(),
        }

        if self.request.method in ('POST', 'PUT'):
            kwargs.update({
                'data': self.request.POST,
                'files': self.request.FILES,
            })
        return kwargs

    def get_profile_initial(self):
        initial = super(UserCreateView, self).get_initial()
        initial = initial.copy()
        initial['user'] = self.object
        return initial

forms.py:
class NewCustomerForm(forms.ModelForm):

    class Meta:
        model = User
        exclude = ['password', 'groups', 'user_permissions', 'last_login']
        widgets = {
            'is_active': forms.HiddenInput(),
            'date_joined': forms.HiddenInput(),
            'username': forms.HiddenInput(),
        }


class CustomerProfileForm(forms.ModelForm):

    class Meta:
        model = Customer
        exclude = ['street', 'city', 'zip_code']
        widgets = {
            'date_of_birth': forms.DateInput(),
            'user': forms.HiddenInput(),
        }

I first create an instance of the class User, save it (everything is OK here). But when it CustomerProfileis created, the form does not pass validation. Namely, the field user, since there is no such value (which was just created) in the original queryset.
Are there any options how to solve this issue? I will be very grateful for your help.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Y
Yura Khlyan, 2016-07-07
@MAGistr_MTM

Thanks everyone, I figured it out.
Just threw out the User field from the form. And when saving the form, I put commit = False, and the user manually registered the field.

if profile_form.is_valid():
            customer_profile = profile_form.save(commit=False)
            customer_profile.user = self.object
            customer_profile.save()
            post_data = self.profile_form_valid(request)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question