Django Edit Form Creates New Instance - python

I am creating a form that allows users to edit an event saved to a django database. The problem is when it runs the code, a new instance is created in the database, the old one remains in the database and both are then available to view in the site
Below is (some of) the HTML form that is used to call the edit view and edit the instance in the database
<div class="modal-footer">
<form action="edit/" method="POST">
{% csrf_token %}
<input type="hidden" name="event_edit_id" id="event_edit_id">
<input class="btn btn-primary btn-block" type="submit" value="Save Changes"/>
</form>
</div>
Next, is the View that is used to edit the event for the id sent with the form:
def edit(request):
if request.method == "POST":
event_id = int(request.POST.get('event_edit_id'))
event = Events.objects.get(pk=event_id)
form = AddEventForm(request.POST or None, instance=event)
if form.is_valid():
form.save()
return redirect('calendar')
I know I am missing something but I just can't see it, any help appreciated!
EDIT
I've noticed that when the code is submitted for edit, it goes straight to /calendar/ instead of /calendar/edit so this is the urls file I use to map the files
urlpatterns = [
path('', views.calendar, name="calendar"),
path('delete/', views.delete, name="delete"),
path('edit/', views.edit, name="edit"),
]

Without seeing your form, I can only guess that there's nothing populating edit_event_id, so the form is saved as a new event. Currently, edit_event_id isn't a bound field, so it doesn't contain any data.

Ok so I got it, and it was impossible for anyone else to get it because the issue was further up in the code than in the I had included in the html.
My error was that I had not changed the code properly after a previous edit. There was another form that was open and I didn't delete the start of the form tag..
Basically, I didn't make sure the HTML tags each had an opening and closing tag.
On this is correct, the code above will work to edit entries :)

Related

Is there a way to extract data from django templates except the POST method

In one of the pages of my website i m trying to create two buttons save and delete. Save as the name suggests saves the data filled into form in my database. Delete deletes this data. I want to access these two buttons separately in my views.py file but the only way i know to detect user input is checking if request.method == 'POST'. But in the case of both the save and delete button POST request is going to be made. How can i differentiate between the click of delete and save button so that i can write different code for each?
Use the name tag in the button to differentiate between POST operations.
For example:
<button name="delete">Delete</button>
And use in condition in view:
if "delete" in request.POST:
Use two separated form, and submit them by ajax seems the easiest way.
view.py
Create 2 views. One for add/update data, and second one for delete data.
def submit_view(...):
if request.POST:
# add data (if form.is_valid, and more)
def delete_view(...):
if request.POST:
# delete data (if form.is_valid, and more)
template
Now add two separated forms in template, and submit them by using ajax.
<form action="/submit" id="submit_form">
<input type="text" id="lname" name="lname" value="Doe"><br><br>
<input type="button" value="submit" id="submit_button">
</form>
<form action="/delete" id="delete_form">
<input type="text" id="lname" name="lname" value="Doe"><br><br>
<input type="button" value="delete" id="delete_button">
</form>
<script>
$('#submit_button').on('click',function(){$('#submit_form').submit();});
$('#delete_button').on('click',function(){$('#delete_form').submit();});
</script>

DJANGO - redirect() not redirecting - appends the current path name to the domain

Basically when a POST request is made, I want to redirect to another page.
def sample(request):
if request.method != "POST":
return render(request,"user/sample.html")
else:
return redirect("https://www.djangoproject.com")
This code works fine when it receives a GET request but when I submit
information, instead of redirecting to the page above, it appends the the template name into the url, Something like this :
http://localhost:8000/sample/sample
No matter what I type into the redirect(), even completely random things it still redirects to sample/sample
I've created multiple django-projects and in every one of them I still get this problem.
I've fixed the problem, leaving this here for anyone in the future.
My problem was in the html file
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit">
the <form action=""> must be an empty string, otherwise it is going to append that to the url.
The problem had nothing to do with the redirect() function.

Django search functionality

I added a search functionality to my website, such that if you goto www.mywebsite.com/search/texthere , it displays all the songs with title=texthere. I would like to add this functionality to my index page.
In my page, there is an input box where users could type the input and the press submit to submit the input but it goes to some another page.
How can I solve this?
urls.py
url(r'^search/(?P<query>[\w\-]+)/$', views.search, name='search'),
index.html
<form action="/search/">
<input type="text" name="query" value="me"><br>
<input type = "submit">
</form>
What I want is when the user clicks submit button, the text from the input box should be used as the query in urls.py Any help would be appreciated. Thanks!
I think you can get this work by using redirect.
Add a url for /search/ endpoint in your form:
url(r'^search/$', views.search_redirect),
In the views:
def search_redirect(request):
query = request.POST.get('query', '')
return redirect('/search/{}/'.format(query))
the form in your index.html should use method 'POST':
<form action="/search/" method="POST">
<input type="text" name="query" value="me"><br>
<input type = "submit">
</form>
When you submit the query string, search_redirect function get the query string and redirects the request to your /search/<query>/ function.
Hope this will help.
EDIT: Your current search url needs query value also to be passed. But in form action only /search/ is there. During the form submission query value will be passed in request.POST and you wont be able to pass the the query value directly in the url like this /search/sample_query
You need to add one more url:
url(r'^search/$', views.search, name='search'),
And in views:
def search(request, query_via_url=false):
# if form submission is true
if request.post:
query_via_form = request.post.get('query', '')
...
# if query value is passed directly via url
if query_via_url:
....

Pyramid: using form data for route matching and POST simultaneously

I'm using Pyramid to build a webapp, and I've got two views where one leads to the other:
config.add_route("new", "/workflow/new")
config.add_route("next", "/workflow/{id}/next")
The new view is really very simple and presents only an HTML form as a Jinja2 template for the user to fill in some information:
<form method="post" action="{{ request.route_url('next',id='') }}" >
<input type="text" name="id" value="Identifier" />
...
<input type="submit" name="next" value="Next" />
</form>
The question here regards the action of that form: how can I use the content of the text input field id, perhaps process it a little, and then pass it on in the route request?
Note that in this scenario the form data is passed from the new view to the next view, and that should stay the same.
When the form is posted, the forms fields will be available in the request object, see
http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/webob.html#request
I believe it is also a good idea to post to the same url (<form action="#" method="post">), so that you can validate the form. Then you can process and redirect to the next url when the form is valid, or recreate the form with errors if it isn't.
So your view may end up something like this;
from pyramid.httpexceptions import HTTPFound
from pyramid.url import route_url
def myview(request):
if request.method == 'POST':
# Validate the form data
if <form validates successfully>:
# Do any processing and saving here.
return HTTPFound(location = route_url('next', id=request.params['id'], request=self.request))
else:
request.session.flash("The form isn't valid.")
# Do some stuff here to re-populate your form with the request.params
return { # globals for rendering your form }
There are already many questions/answers addressing this, such as How can I redirect after POST in Pyramid?

Pyramid self.request.POST is empty - no post data available

I'm currently working on a pyramid project, however I can't seem to submit POST data to the app from a form.
I've created a basic form such as:
<form method="post" role="form" action="/account/register">
<div class="form-group">
<label for="email">Email address:</label>
<input type="email" class="form-control" id="email" placeholder="you#domain.com">
<p class="help-block">Your email address will be used as your username</p>
</div>
<!-- Other items removed -->
</form>
and I have the following route config defined:
# projects __init__.py file
config.add_route('account', '/account/{action}', request_method='GET')
config.add_route('account_post', '/account/{action}', request_method='POST')
# inside my views file
#view_config(route_name='account', match_param="action=register", request_method='GET', renderer='templates/account/register.jinja2')
def register(self):
return {'project': 'Register'}
#view_config(route_name='account_post', match_param="action=register", request_method='POST', renderer='templates/account/register.jinja2')
def register_POST(self):
return {'project': 'Register_POST'}
Now, using the debugger in PyCharm as well as the debug button in pyramid, I've confirmed that the initial GET request to view the form is being processed by the register method, and when I hit the submit button the POST request is processed by the *register_POST* method.
However, my problem is that debugging from within the *register_POST* method, the self.request.POST dict is empty. Also, when I check the debug button on the page, the POST request is registered in the list, but the POST data is empty.
Am I missing something, or is there some other way of access POST data?
Cheers,
Justin
I've managed to get it working. Silly me, coming from an ASP.NET background forgot the basics of POST form submissions, and that's each form field needs a name== attribute. As soon as I put them in, everything started working.
That does nothing, I belive.
return {'project': 'Register_POST'}
POST parameters are stored inside request, so you have to do something like this.
def register_POST(self, request):
return {'project': request.POST}
To access email input (which has to be named, for example: name="email"), use get() method:
request.POST.get('email')
<form method="post" role="form" action="/account/register"> {% csrf_token %}
Try using "csrf token". hope it works. remaining code looks fine.

Categories

Resources