简体   繁体   English

在 Django 中测试 POST 请求

[英]Testing a POST request in Django

I have a function in my Django App that add a product to a favorite database.我的 Django 应用程序中有一个 function ,可将产品添加到收藏的数据库中。 I need to write a test of it.我需要为它写一个测试。 Everything except the test runs perfect.除了测试之外的一切都运行完美。

def add(request):
    data = {'success': False} 
    if request.method=='POST':
        product_id = request.POST.get('product_id')
        sub_product_id = request.POST.get('sub_product_id')
        user = request.user       
        sub_product = Product.objects.get(pk=int(sub_product_id))
        original_product = Product.objects.get(pk=int(product_id))       
        p = SavedProduct(username= user, sub_product=sub_product, original_product = original_product)
        p.save()        
        data['success'] = True
    return JsonResponse(data)

My 'product' comes from an AJAX call and I get it from this HTML:我的“产品”来自 AJAX 调用,我从这个 HTML 得到它:

 <div class='sub_button'>            
        <form class="add_btn" method='post'>
        <input type="hidden" class="product_id" value="{{ product.id }}">
        <input type="hidden" class="sub_product_id" value="{{ sub_product.id }}">
        <button class='added btn'><i class='fas fa-save'></i></button>                                
   </div>

And that AJAX call: AJAX 调用:

$(".row").on('click', '.sub_button', function(event) {
  let addedBtn = $(this);
  event.preventDefault();
  event.stopPropagation();
  var product_id = $(this).find('.product_id').val();
  var sub_product_id = $(this).find('.sub_product_id').val();     
  var url = '/finder/add/';   
  $.ajax({        
      url: url,        
      type: "POST",
      data:{
          'product_id': product_id,
          'sub_product_id': sub_product_id,            
          'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
      },
      datatype:'json',
      success: function(data) {
        if (data['success'])            
        addedBtn.hide();             
      }
  }); 
});

My urls.py:我的 urls.py:

app_name = 'finder'
urlpatterns = [           
    path('add/', views.add, name='add'),
    path('sear/', views.search, name='sear'),
    path('sub/', views.sub, name='sub') ]

This is the test I am running:这是我正在运行的测试:

class AddDeleteProduct(TestCase):   
    
    def setUp(self):
        User.objects.create(username='Toto', email='toto@gmail.com')            
    def test_add_product(self):       
        old_count = SavedProduct.objects.count()
        payload = {'product_id': 12, 'sub_product_id': 22}        
        response = self.client.post(reverse('finder:add', kwargs=payload))
        new_count = SavedProduct.objects.count()
        self.assertEqual(new_count, old_count + 1)

But I get this error message:但我收到此错误消息:

Traceback (most recent call last):  

File "/home/pi/Documents/P_11_before/Pur_Beurre_Reload/finder/tests.py", line 155, in test_add_product
    response = self.client.post(reverse('finder:add', kwargs=payload))
  File "/home/pi/.local/lib/python3.7/site-packages/django/urls/base.py", line 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/home/pi/.local/lib/python3.7/site-packages/django/urls/resolvers.py", line 677, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'add' with keyword arguments '{'product_id': 12, 'sub_product_id': 22}' not found. 1 pattern(s) tried: ['finder/add/$']

What you need is to have input fields in your html template.您需要在 html 模板中有输入字段。

urls网址

path('add/<int:product_id>/<int:sub_product_id>', ...)

views意见

def add(request):
    data = {'success': False} 
    if request.method=='POST':
        product_id = request.POST.get('product_id')
        sub_product_id = request.POST.get('sub_product_id')
        user = request.user       
        sub_product = Product.objects.get(pk=int(sub_product_id))
        original_product = Product.objects.get(pk=int(product_id))       
        p = SavedProduct(username= user, sub_product=sub_product, original_product = original_product)
        p.save()        
        data['success'] = True
    return JsonResponse(data)

html html

<div class='sub_button'>            
     <form class="add_btn" method='post'>
     <input type="hidden" name="product_id" value="{{ product.id }}">
     <input type="hidden" name="sub_product_id" value="{{ sub_product.id }}">
     <button class='added btn'><i class='fas fa-save'></i></button>                                
 </div>

test测试

 class AddDeleteProduct(TestCase):   
    
    def setUp(self):
        User.objects.create(username='Toto', email='toto@gmail.com')
            
    def test_add_product(self):       
        old_count = SavedProduct.objects.count()
        payload = {'product_id': 12, 'sub_product_id': 22}
        response = self.client.post(reverse('finder:add', kwargs=payload))
        new_count = SavedProduct.objects.count()
        self.assertEqual(new_count, old_count + 1)

I think, the method of the form has to be POST and not post .我认为,表单的方法必须是POST而不是post Then the code would look like:然后代码将如下所示:

<div class='sub_button'>            
     <form class="add_btn" method='POST'>
     <button class='added btn' value= '{{product.id }} {{ sub_product.id }}' ><i class=' fas fa-save'></i></button>                                
 </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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