Выход из системы через GET-запросы устарел и будет удален в Django 5.0
Я получаю это предупреждение при выполнении тестов с помощью selenium и pytest. Вот метод теста:
def test_registration(
self, driver, live_server, valid_user_data, django_user_model
):
selenium_signup(driver, live_server, valid_user_data, django_user_model)
selenium_sign_in(driver, live_server, valid_user_data)
page_source = driver.page_source.lower()
assert 'sign in' not in page_source
assert 'sign up' not in page_source
assert 'sign out' in page_source
driver.find_element(By.ID, 'btnGroupDrop1').click()
driver.find_element(By.XPATH, '//*[contains(text(), "Sign out")]').click()
assert 'sign in' in page_source
assert 'sign up' in page_source
Здесь генерируется предупреждение:
driver.find_element(By.XPATH, '//*[contains(text(), "Sign out")]').click()
Вот кнопка:
<li><a class="dropdown-item" href={% url 'signout' %}>Sign out</a></li>
В представлении используется django LogoutView и вот как оно определено
from django.contrib.auth.views import LogoutView
urlpatterns = [
path('signout/', LogoutView.as_view(), name='signout'),
...
]
Что было бы чистым способом исправить это?
Как указано в документе, вы должны сделать вызов API HTTP POST
. Поэтому будет лучше, если вы замените "гиперссылку" на "кнопку" (или что-то подобное, имитирующее HTTP POST
запрос).
Я бы выбрал простую реализацию кнопки, как показано ниже.
# logout-confirmation.html
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button type="submit">Sign Out</button>
</form>
# views.py
class LogOutRenderView(TemplateView):
template_name = "logout-confirmation.html"
#urls.py
from django.contrib.auth.views import LogoutView
from .vies import LogOutRenderView
urlpatterns = [
path("logout-confirmation/", LogOutRenderView.as_view(), name="logout-confirmation"),
path("logout/", LogoutView.as_view(), name="logout"),
]
Примечание: Вы можете заменить гиперссылку блоком <form...> ... </form>
.
Нужно ли нажимать на кнопку? Или вам достаточно просто отправить POST-запрос на url, который использует кнопка?
Если да, то вы можете создать фиктивную форму с помощью javascript, чтобы имитировать кнопку отправки:
# Fetch CSRF token from cookies
csrf_token = driver.get_cookie('csrftoken')['value']
# Inject a form using JavaScript that posts to the logout URL with a CSRF token
js_script = f"""
var form = document.createElement('form');
form.method = 'post';
form.action = '/signout/';
var csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = 'csrfmiddlewaretoken';
csrfInput.value = '{csrf_token}';
form.appendChild(csrfInput);
document.body.appendChild(form);
form.submit();
"""
driver.execute_script(js_script)