urlpatterns=[
path('login/',views.LoginUser,name='login'),
path('logout/',views.LogoutUser,name='logout'),
path('register/',views.RegisterUser,name='register'),
path('delete/<str:pk>',views.DeleteUser,name='delete'),
path('',views.home,name='home'),
#path('usersSettings/',views.UserSettings,name='userSettings'),
path('users/<str:pk>/',views.users,name='users'),
path('parameters/',views.parameters,name='parameters'),
path('EbotManual/',views.EbotManual,name='EbotManual'),
path('LedManual/',views.LedManual,name='LedManual'),
path('TestRutins/',views.TestRutins,name='TestRutins')
]
I am designing a website based on django. I want to update the user information and delete the user if wanted in the same page. I created updating and it works properly. But when I address the delete user function to same html file , the button that I want it to delete user also updates just like the other button. I need both buttons to work for their own purposes. I thought that without changing anything assigning delete function to button might help thats why I wrote the title like that. Thank you!
<div class="login--wrapper">
<form method="POST" class="form">
{% csrf_token %}
<div class="center">
<h1>Kullanıcı Ayarları</h1>
{% csrf_token %}
{% for field in form %}
<div class="mb-3">
<label for="exampleInputPassword1" class="from-label">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Update Info</button>
<button type="submit" class="btn btn-primary">Delete User </button>
</div>
def DeleteUser(request,pk):
user=DataEbotUser.objects.get(id=pk)
if request.method=='POST':
user.delete()
context={'user':user}
return render(request,'home/UsersPage.html',context)
def users(request,pk):
user=DataEbotUser.objects.get(id=pk)
form=EditUserForm(instance=user)
if request.method=='POST':
form=EditUserForm(request.POST, instance=user)
if form.is_valid():
form.save()
context={'form':form , 'users':users}
return render(request,'home/UsersPage.html',context)
url patterns:
urlpatterns=[
path('login/',views.LoginUser,name='login'),
path('logout/',views.LogoutUser,name='logout'),
path('register/',views.RegisterUser,name='register'),
path('delete/<str:pk>',views.DeleteUser,name='delete'),
path('',views.home,name='home'),
#path('usersSettings/',views.UserSettings,name='userSettings'),
path('users/<str:pk>/',views.users,name='users'),
path('parameters/',views.parameters,name='parameters'),
path('EbotManual/',views.EbotManual,name='EbotManual'),
path('LedManual/',views.LedManual,name='LedManual'),
path('TestRutins/',views.TestRutins,name='TestRutins')
]
The problem is that your two buttons submit the form to the same page that rendered the form. There is no way to tell them apart.
If you want each button to perform a different action, one way to do this would be:
<button type="submit" class="btn btn-primary">Update Info</button>
<a class="btn btn-danger" type="button" href="{% url 'delete' user.pk %}">Delete User</a>
Since the function users is the only one to manage the update of the user's information based on the form data, the button Update Info remains in the form of submit button.
The Delete User button on the other hand is different. It simply calls the function DeleteUser passing it a pk which will be used to delete a user.
Here are some things to consider:
The function DeleteUser must not be called directly. It is the function users which must render the page.
You have to render the user object in the context of your function users, to be able to retrieve the pk of the user who will be used for the button delete
Function DeleteUser must not render the template but redirect to another url like home. Something like return redirect('home')
Related
I am working on developing a permitting app using django. This is my first django project so bear with me here...
we have a default utility permit that contains some basic info like property owner and address. Then from that you can attach a sewer, or water or row or any combination of related tables to the permit. Basically I am looking for a way to return a page with the default utility permit then have a series of links or buttons to add more forms to that page.
I made some model forms for each of the models and can display them individually on the page
forms.py
class UtilityPermitForm(forms.ModelForm):
class Meta:
model = UtilityPermit
fields = ['...']
class SewerPermitForm(forms.ModelForm):
class Meta:
model = SewerPermit
fields = ['...']
class WaterPermitForm(forms.ModelForm):
class Meta:
model = WaterPermit
fields = ['...']
I successfully added them to a list and could iterate through and get them to add
views.py
class BuildForms(View):
permits = []
utility_form = UtilityPermitForm
sewer_form = SewerPermitForm
water_form = WaterPermitForm
permits.append(utility_form)
permits.append(sewer_form)
permits.append(water_form)
template_name = 'engineering/UtilityPermitForm2.html'
def get(self, request, *args, **kwargs):
out_permits = []
for form in self.permits:
out_permits.append(form())
return render(request, self.template_name, {'form': out_permits})
def post(self, request, *args, **kwargs):
if request.GET.get('testButton'):
return HttpResponse("I guess")
form = self.utility_form(request.POST)
return render(request, self.template_name, {'form': form})
def add_permit(self, request, permit):
# need to get a thing to add a permit to the list
pass
.html
{% block content %}
<div>
<form class="site_form" action={% url 'engineering:utility_permit' %} method="post">
{% csrf_token %}
{% for item in form %}
{{ item }}
<hr>
{% endfor %}
<input type="submit" value="Submit">
</form>
</div>
{% endblock content %}
so again, my problem is I want to start with a one permit and then have links or buttons to add each form as needed. I'm a bit at a loss here and any help would be greatly appreciated.
EDIT:
so I have this base permit that comes up when a user navigates to it like so, and I want to have a user click the add sewer permit button or link or whatever
and then the corresponding permit will come up
you can create multiple same form in one page dynamically using formset
see Documentation
and maybe this tutorial is exactly what you are looking for.
EDITED
if I understand your question correctly, how about this:
first, it would be better to separate your form with dictionaries instead of list in your views.py
context = {
'utility_form': self.utility_form,
'sewer_form': self.sewer_form,
'water_form': self.water_form
}
return render(request, self.template_name, context)
then in your .html file,
if you want to add one form each time you click the button, my trick is:
show your base permit form first (said utility_form), button to add other form, and hide your other form first.
<div class="form-container">
<form class="site_form" action={% url 'engineering:utility_permit' %} method="post">
{% csrf_token %}
{{ utility_form }}
<div id="additional-forms"></div> <!-- notice this div -->
<hr>
<input type="submit" value="Submit">
</form>
</div>
<button class="add-sewer-form">Sewer Permit</button>
<div id="sewer-form-template" style="display: none;">
<div class="sewer-form-container">
{{ sewer_form }}
</div>
</div>
and then using jquery to add onclick listener, clone that hidden form, then insert it after base form (actually inside div with id additional-forms).
$('.add-sewer-form').click(function(){
let sewer_form = $('#sewer-form-template .sewer-form-container:first').clone(true);
$(sewer_form).appendTo($('#additional-forms'))
});
I haven't test it yet, but when you click the add button, it should be give result like this:
<div class="form-container">
<form class="site_form" action={% url 'engineering:utility_permit' %} method="post">
{% csrf_token %}
{{ utility_form }}
<div id="additional-forms">
<div class="sewer-form-container">
{{ sewer_form }}
</div>
</div>
<hr>
<input type="submit" value="Submit">
</form>
</div>
<button class="add-sewer-form">Sewer Permit</button>
<div id="sewer-form-template" style="display: none;">
<div class="sewer-form-container">
{{ sewer_form }}
</div>
</div>
Hope it can answer your question :)
First add the button
<button><button>
Then add onclick attribute to it which will help react on click
<button onclick='do'><button>
Then create script that contain the function to display the other form
<script>
function do() {
document.getElementById('form').innerHTML ='add your form here'
}
</script>
all together
<button onclick='do'><button>
<script>
function do() {
document.getElementById('form').innerHTML ='add your form here'
}
</script>
Hi i am using django + bootstrap4 to render forms. I have 'submit' and 'cancel' buttons on the forms. i am using ModelForm with Validators assigned to most of the form attributes.
template file
<form action="{% url 'actor-create' %}" method="post" class="w-25 mx-auto">
{% csrf_token %}
{% bootstrap_form form layout="horizontal" %}
<button class="btn btn-primary" type="submit"><i class="fas fa-plus"></i> Save</button>
<button class="btn btn-primary" type="submit"><i class="fas fa-times"></i> Cancel</button>
</form>
in the view
def actor_create(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
print(request.POST)
if "cancel" in request.POST:
return HttpResponseRedirect('/')
..... rest of the code
When cancel button is pressed validation of the form attributes prevents the form from submitting. so view functionality never gets executed.
I want to know how to avoid validation when form is cancelled?
Following Q&A has a JavaScript based solution, I preferably don't want to write such code for every form in my website.
How to cancel form submission?
as suggested by Iain Shelvington making it a 'a' worked for me!
<i class="fas fa-times"></i> Cancel
I have a page that pulls out entries from the database as 'users' and lists them. A typical result looks like this:
John
Marty
Tom
Jane
Chris
Now I would like to click on a specific the name and go to their specific page. For this, I have a form that posts to a view that expects the user that has been "clicked"
So far, I have a form inside a loop that goes through each 'user' in 'users' table. The setup works fine but the major problem is that the form element 'name' is replaced by the last user. No matter, whose name I click it always passes the last user's username.
{% for user in users %}
<h1>{{ user.firstName }} {{ user.lastName }}</h1>
<form action="/friend_profile/" method="post" accept-charset="utf-8">
<input type="hidden" name="selectedFriend" value ={{ user.userName }}>
<button type="submit" value="view profile">
{% endfor %}
I am not using DJango forms and just using request.method == 'POST' for receiving variables.
So my dumb question would be, is there a way to dynamically create 'name' form element and submit its contents specific to the user? Right now, the form always submits the user "Chris" no matter which user I click because its the last one on the list.
Right now, the form always submits the user "Chris" no matter which user I click because its the last one on the list.
That's because you didn't close your <form> tag, so the browser sees one big bunch of nested forms.
Also, you need to quote and escape the value attribute in your hidden input:
<form action="/friend_profile/" method="post" accept-charset="utf-8">
<input type="hidden" name="selectedFriend" value="{{ user.userName|escape }}">
<button type="submit" value="view profile">
</form>
I don't usually have a lot of trouble with django form submission, but i can't seem to figure out what am not doing right for my code to work. Done some reading here at stackoverflow but no luck.
In my template, i define a form that is rendered within a twitter bootstrap modal,
<div class="modal-body">
<form method="post" action="{%url 'item_order' item.id %}">
<input class="btn btn-large btn-success" type="submit" name="submit" value="add to order"/>
</form>
In the form header, i want to explicitly have the form submit to this view,
def show_item(request,id):
a = Item.objects.get(pk=id)
if request.method == 'POST':
form = partial_order_item_form()
final_form = form(request.POST)
# check validation of posted data
if final_form.is_valid():
order.add_to_order(request,a)
url =urlresolvers.reverse('order_index',kwargs={'id':a.id})
# redirect
return HttpResponseRedirect(url)
urls.py
url(r'^item/(?P<id>\d+)/$',show_item, name="item_order")
To my suprise, the form will not submit to this view, in fact it will not do anything at all. This beats my understanding, i thought if i have explicitly set the action in the form header, it would work as i intend it to.
What am not doing right? Links are appreciated as well.
Edit
Inspecting with firebug as pointed out by #danihp, i have learnt that when the browser renders the page it closes the form before rendering all django template logic i want it to.
<form method="post" action="orders/item/2"></form>
<input class="btn btn-large btn-success" type="submit" name="submit" value="add to order"/>
so when i submit nothing happens because the input element is not in the form.
SOLVED
Check out my answer.
Looking aroung i found the same problem and solution. It happens my html markup was poorly written, the mentioned problem and solution helped figure it out.
I would like to use a button to update a field (claimant) in one of my models (PieceInstance) and then redirect the user to a page where he sees all of the claimed instances.
The code is the following:
button:
(looping through all instances)
<a target="_blank"
method="POST"
class="button"
href="{% url 'claim' pk=instance.pk %}">
Claim
</a>
views.py
def claim(request, pk):
piece_instance = PieceInstance.objects.get(pk=pk)
piece_instance.claimant = request.user
piece_instance.save()
return HttpResponseRedirect(reverse('my-claimed'))
urls.py
urlpatterns += [
path('myclaimedpieces/<uuid:pk>', views.claim, name='claim'),
]
It runs smoothly but does not update the field in the model and hence the content on the redirected page is still empty.
Help is much appreciated!
It looks almost good to me. The only thing is the use of method in a <a> tag makes no sense. You should either use a pure link:
<a target="_blank"
class="button"
href="{% url 'claim' pk=instance.pk %}">
Claim
</a>
Or use a form with a real button (not a link formatted as a button):
<form method="POST" action="{% url 'claim' pk=instance.pk %}">
<button type="submit"
class="button">
Claim
</button>
</form>