Метод post
Метод post класса RequestFactory предназначен для создания
имитационных POST-запросов в тестовой среде Django. Он позволяет
тестировать представления, обрабатывающие данные форм и AJAX-запросы,
без необходимости запускать реальный веб-сервер. Метод принимает
путь к представлению, данные для отправки и необязательные параметры
заголовков и формата данных. В отличие от тестового клиента,
RequestFactory не выполняет полный цикл обработки запроса,
а только создаёт объект запроса, который можно передать в представление
напрямую.
Синтаксис
from django.test import RequestFactory
factory = RequestFactory()
request = factory.post(path, data=None, content_type='application/x-www-form-urlencoded', **extra)
Параметры метода:
-
path- URL-путь, к которому обращается запрос -
data- словарь с данными формы или строка с JSON-данными -
content_type- тип содержимого запроса (по умолчанию application/x-www-form-urlencoded) -
**extra- дополнительные параметры заголовков (например, HTTP_USER_AGENT, REMOTE_ADDR)
Пример
Давайте создадим простой POST-запрос для отправки данных формы в представление, которое создаёт новую статью:
from django.test import RequestFactory
from django.http import HttpResponse
from myapp.models import Article
def create_article_view(request):
if request.method == 'POST':
title = request.POST.get('title')
content = request.POST.get('content')
Article.objects.create(title=title, content=content)
return HttpResponse('Article created')
return HttpResponse('Invalid method')
factory = RequestFactory()
data = {'title': 'Test Article', 'content': 'This is a test content'}
request = factory.post('/articles/create/', data)
response = create_article_view(request)
print(response.content.decode())
Результат выполнения кода:
"Article created"
Пример
Давайте создадим POST-запрос с JSON-данными для обработки API-эндпоинта:
import json
from django.test import RequestFactory
from django.http import JsonResponse
from myapp.models import Article
def api_create_article(request):
if request.method == 'POST':
try:
data = json.loads(request.body)
article = Article.objects.create(
title=data['title'],
content=data['content']
)
return JsonResponse({'id': article.id, 'status': 'success'})
except (KeyError, json.JSONDecodeError):
return JsonResponse({'status': 'error'}, status=400)
factory = RequestFactory()
json_data = {'title': 'API Article', 'content': 'JSON content'}
request = factory.post(
'/api/articles/',
data=json.dumps(json_data),
content_type='application/json'
)
response = api_create_article(request)
print(response.content.decode())
Результат выполнения кода:
"{"id": 1, "status": "success"}"
Пример
Давайте протестируем обработку POST-запроса с дополнительными заголовками, имитирующими реальный браузер:
from django.test import RequestFactory
from django.http import HttpResponse
from myapp.models import Comment
def add_comment_view(request):
if request.method == 'POST':
author = request.POST.get('author')
text = request.POST.get('text')
Comment.objects.create(author=author, text=text)
return HttpResponse('Comment added')
return HttpResponse('Invalid method')
factory = RequestFactory()
data = {'author': 'John Doe', 'text': 'Great article!'}
extra_headers = {
'HTTP_USER_AGENT': 'Mozilla/5.0',
'HTTP_REFERER': 'https://example.com/previous-page/',
'REMOTE_ADDR': '192.168.1.100'
}
request = factory.post('/comments/add/', data, **extra_headers)
print(request.user_agent)
print(request.META.get('REMOTE_ADDR'))
Результат выполнения кода:
"Mozilla/5.0"
"192.168.1.100"
Пример
Давайте протестируем обработку POST-запроса с файловыми данными, используя имитацию загрузки файла:
from django.test import RequestFactory
from django.core.files.uploadedfile import SimpleUploadedFile
from myapp.models import Document
def upload_document_view(request):
if request.method == 'POST':
file = request.FILES['document']
doc = Document.objects.create(
name=request.POST.get('name'),
file=file
)
return HttpResponse(f'Document {doc.id} uploaded')
factory = RequestFactory()
uploaded_file = SimpleUploadedFile(
'test.txt',
b'This is test content',
content_type='text/plain'
)
data = {'name': 'Test Document'}
request = factory.post(
'/documents/upload/',
data={'name': 'Test Document', 'document': uploaded_file}
)
request.FILES = {'document': uploaded_file}
response = upload_document_view(request)
print(response.content.decode())
Результат выполнения кода:
"Document 1 uploaded"
Смотрите также
-
класс
RequestFactory,
который предоставляет фабрику для создания тестовых запросов -
метод
get,
который создаёт имитационный GET-запрос -
класс
Client,
который выполняет полный цикл обработки запроса в тестах -
метод
assertContains,
который проверяет наличие содержимого в ответе