简体   繁体   中英

django: how to merge a class based view with a function based view

for some reason i wanted to use the django class based form view "PasswordResetView" in my template that already has a function based view which is the home view, so i thought that i should copy paste the "PasswordResetView" from django's source code in my views.py file and change what is needed but i always face some errors because i'm not familiar with class based views
here is my view in my views.py file:

def home(request):
    
    user = request.user
    signin_form = SigninForm()
    signup_form = SignupForm()
   
        if 'signin_form' in request.POST:
            signin_form = SigninForm(request.POST)
            if signin_form.is_valid():
                    email = request.POST['email']
                    password = request.POST['password']
                    user = authenticate(email=email, password=password)
                    if user:
                        login(request, user)
                    elif user is None:
                        messages.error(request, 'ُEmail or password is incorrect')



        if 'signup_form' in request.POST:
            signup_form = SignupForm(request.POST)
            if signup_form.is_valid():
                signup_form.save()
                full_name = signup_form.cleaned_data.get('full_name')
                email = signup_form.cleaned_data.get('email')
                raw_password = signup_form.cleaned_data.get('password1')
                account = authenticate(email=email, password=raw_password)
                login(request, account)
                
    


    context = {'signin_form': signin_form,'signup_form': signup_form}

    return render(request, 'main/home.html', context)

here is the "PasswordResetView" from django's source code:

from django.urls import reverse, reverse_lazy
from django.contrib.auth.tokens import default_token_generator
from django.views.generic.edit import FormView
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

class PasswordContextMixin:
    extra_context = None

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'title': self.title,
            **(self.extra_context or {})
        })
        return context


class PasswordResetView(PasswordContextMixin, FormView):
    email_template_name = 'registration/password_reset_email.html'
    extra_email_context = None
    form_class = PasswordResetForm
    from_email = None
    html_email_template_name = None
    subject_template_name = 'registration/password_reset_subject.txt'
    success_url = reverse_lazy('password_reset_done')
    template_name = 'registration/password_reset_form.html'
    title = _('Password reset')
    token_generator = default_token_generator

    @method_decorator(csrf_protect)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def form_valid(self, form):
        opts = {
            'use_https': self.request.is_secure(),
            'token_generator': self.token_generator,
            'from_email': self.from_email,
            'email_template_name': self.email_template_name,
            'subject_template_name': self.subject_template_name,
            'request': self.request,
            'html_email_template_name': self.html_email_template_name,
            'extra_email_context': self.extra_email_context,
        }
        form.save(**opts)
        return super().form_valid(form)


INTERNAL_RESET_SESSION_TOKEN = '_password_reset_token'

in my urls.py

    path('', views.home, name='home'),

you can use class based view with function based view. all you need is to write all routes in urls.py

from django.contrib.auth import views as auth_views

    path('', views.home, name='home'),
    path('password-reset', auth_views.PasswordResetView.as_view() ,name='password-reset'),

I assume that you want to access the PasswordResetView 's form from your home view without changing the page and if so you don't have to have class based view for PasswordResetView .

All you need to do is import django built in auth views .

urls.py

from django.contrib.auth import views as auth_views

path('', views.home, name="home"), # your home page url

# password reset url
path('', auth_views.PasswordResetView.as_view(template_name="myapp/home.html"), name="password_reset"), 

in your template (home.html)

<form action="{% url 'password_reset' %}" method="POST">
   {% csrf_token %}
   {{form.as_p}}
   <button type="submit">Submit</button>
</form>

Now whenever you click the submit button django will go the password_reset url and do the job for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM