3

I've searched some of the related questions and I couldn't figure out how to do it. That is why I am posting a new question here.

I have a base.html file and there is a button which should run a function from views.py file. Here is the button code:

<form role="form" action="" method="POST">
{% csrf_token %}
  <input type="submit" class="btn" value="Click" name="mybtn">
</form>

And here is my function from views.py file:

def create_new_product(request):
    if request.method == 'POST':
        '''Execute the code here'''
    return render (request, 'products/base.html')

And in my Products' urls.py file:

app_name = 'products'
urlpatterns = [
    path('create-new-product/', views.create_new_product),
    path('', views.IndexView.as_view(), name='base'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]

Normally I have an IndexView class in views.py file which lists all the current products and what I expect from the above function is that it will generate new products and new products will also be listed in 'products' page.

The above function is not inside the IndexView class by the way.

Nathan
  • 449
  • 1
  • 7
  • 23
Hektor
  • 105
  • 3
  • 14
  • 3
    Well by writing `action="#"`, you stay on the same page, regardless what the request returns: https://stackoverflow.com/questions/8395269/what-do-form-action-and-form-method-post-action-do – Willem Van Onsem Jul 19 '18 at 14:10
  • I removed # from there but the function does not work. I do not see any new products generated. Normally the function works. Now I am only trying to bind it to a button on the products page. By the way, I also checked the link you shared, thank you for that. – Hektor Jul 19 '18 at 14:19
  • Are you sure you send it to the correct view. I find creating a new element with a get very strange (it is actually breaking the contract that a GET should not have any side-effects at all). – Willem Van Onsem Jul 19 '18 at 14:21
  • I am not sure. I think the 'name' attribute is the key there and I can bind the button click request with this key to the function. That is why I used this 'mybtn' in the function inside get. I am very new to it. – Hektor Jul 19 '18 at 14:28
  • 1
    I'm saying that this is completely against how HTTP is supposed to work, a GET request should be *idempotent*, meaning that if I refresh thousands of times, the database is exactly the same as before: https://spring.io/understanding/REST#get – Willem Van Onsem Jul 19 '18 at 14:29
  • I think I understand what you mean. In my case, the database will generate thousands of copy if I click the button a thousands of times? However I think this problem will be my second problem because I couldn't solve the button click operation. – Hektor Jul 19 '18 at 14:38
  • I found the problem. I updated my question too. I added Products' urls.py file in the question. I left the missing parts in the case that you may post the answer and I can accept it. There are two missing parts and the first one is that in Products' urls.py file `path('create-new-product/', views.create_new_product)` line should also have `name='create_new_product'` parameter. The second one is that in base.html file button action should like this `action="{% url 'products:create_new_product' %}"`. – Hektor Jul 20 '18 at 14:37

2 Answers2

0

You will stay on the same page with action="#"
Try instead action="" so you will stay on the same page but reloaded.
Update:
Read your comment.
The name argument is useful to call your url in Django template like :

path('create-new-product/', views.create_new_product, name='create_new_product')

The app_name = 'products' is very important. It tells Django where to check your path. So you can call your view everywhere in your project by:

<a href="{% url 'products:create_new_product' %}">...</a>
<form action="{% url 'products:create_new_product' %}">...</form>
Wariored
  • 1,303
  • 14
  • 25
  • also `action=""` is equivalent to not mentioning it. – Gahan Jul 19 '18 at 14:15
  • I tried but the function does not work. It seems that the button cannot give the command to the function. – Hektor Jul 19 '18 at 14:21
  • Can I see your urls.py to check if you sent it to the right views – Wariored Jul 19 '18 at 14:29
  • I added a new comment above. It shows the answer. You can check it. If you update your answer accordingly, I can accept it and so the other users can get benefit from this problem. Thank you. – Hektor Jul 20 '18 at 14:39
0

you can either use browser fetch api or jquery ajax to implement search functionality

  1. include a js script to your template file
  2. include this js snippet
$(elementSelector).on("click", async (e) => {
 const fetchOptions = {}
 const response = await fetch(YOUR_URL, {...fetchOptions});
 const responseUrl = response.url // see fetch api docs
 window.location = responseUrl // if you want to redirect
)