django: как объединить представление на основе классов с представлением на основе функций

#python #django #django-forms #django-views #django-class-based-views

#python #django #django-forms #django-представления #django-class-based-views

Вопрос:

по какой-то причине я хотел использовать представление формы на основе классов django «PasswordResetView» в моем шаблоне, в котором уже есть представление на основе функций, которое является домашним представлением, поэтому я подумал, что мне следует скопировать и вставить «PasswordResetView» из исходного кода django в моем views.py файл и измените то, что нужно, но явсегда сталкиваюсь с некоторыми ошибками, потому что я не знаком с представлениями на основе классов.
views.py файл:

 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)
  

вот «PasswordResetView» из исходного кода django:

 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'
  

в моем urls.py

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

Ответ №1:

Я предполагаю, что вы хотите получить доступ PasswordResetView к форме ‘s из своего home view , не меняя страницу, и если это так, вам не нужно иметь представление на основе классов PasswordResetView .

Все, что вам нужно сделать, это импортировать встроенный django 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"), 
  

в вашем шаблоне (home.html )

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

Теперь всякий раз, когда вы нажимаете кнопку отправки, django отправляет password_reset URL-адрес и выполняет работу за вас.

Комментарии:

1. я пробовал это, но это не сработало, эта форма не отображается в шаблоне, она пуста, она отображает только кнопку (в auth_views нет атрибута с именем password_reset, мне пришлось изменить его на PasswordResetView, я отредактирую ваш ответ)

2. о, да, это моя ошибка, я никогда этого не замечал.

3. у вас есть какое-либо другое решение, я застрял!

4. Где вы застряли

Ответ №2:

вы можете использовать представление на основе классов с представлением на основе функций. все, что вам нужно, это записать все маршруты в 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'),
  

Комментарии:

1. но таким образом я могу использовать его только в другом шаблоне, а не в шаблоне домашней страницы, чего я не хочу