I've been coding in the framework django for two weeks and now I am learning to delete products.
Here's the html code I've done:
{% extends 'base.html' %}
{% block content %}
<form action = '.' method= 'POST'> {% csrf_token %}
<h1>Do you want to delete the product "{{ object.title }}"?</h1>
<p><input type= 'submit' value = 'Yes' /> <a href='../'>Cancel</a></p>
</form>
{% endblock %}
And the function I've coded to delete the product
def product_delete_view(request, my_id):
obj = get_object_or_404(Product, id = my_id)
if request.method == "POST":
obj.delete()
context = {
'object': obj
}
return render(request,"products/product_delete.html", context)
Here's my url path:
path('products/<int:my_id>/delete', product_delete_view, name= 'product-delete')
However, my product doesn't get deleted.
Try redirecting somewhere after the deletion is complete, as the delete command deletes it from the database but if their as an instance in python live it will stay on until the page is either reloaded or left.
Related
I am running the latest Flask, Python 3.10. The app is installed on a Windows IIS Server. I have three forms on a single page. There is one submit button. Each form has a unique ID.
When I fill out one or all of the forms and hit the Submit button there is a view Class handler for the POST request. It is being called but the form data is missing.
One of the form elements looks like the following; the other two are similar but without the render_submit_field call:
<form id="add_session_form" action="{{ url_for('session_api') }}" method="POST" novalidate
role="form">
{{ session_form.hidden_tag() }}
{% for field in session_form %}
{% if not field.flags.hidden %}
{% if field.type == 'BooleanField' %}
{{ render_checkbox_field(field, tabindex=loop.index * 300) }}
{% elif field.type == 'SelectField' or field.type == 'SelectMultipleField' %}
{{ render_select_field(field, tabindex=loop.index * 300) }}
{% elif field.type == 'SubmitField' %}
{{ render_submit_field(field, tabindex=loop.index * 300) }}
{% else %}
{{ render_field(field, tabindex=loop.index * 300) }}
{% endif %}
{% endif %}
{% endfor %}
</form>
The POST method of the view Class looks like:
#staticmethod
def post():
try:
db_session = db()
school_form = SchoolForm(obj=current_user)
class_form = ClassForm(obj=current_user)
session_form = SessionForm(obj=current_user)
school_list = SchoolAPI.get_all_schools()
if school_form.validate_on_submit():
# Copy form fields to user_profile fields
school = School()
school_form.populate_obj(school)
db_session.add(school)
db_session.commit()
school_form = SchoolForm()
if class_form.validate_on_submit():
class_ = Class()
class_form.populate_obj(class_)
db_session.add(class_)
db_session.commit()
classes_form = ClassForm()
if session_form.validate_on_submit():
session = Session()
session_form.populate_obj(session)
db_session.add(session)
db_session.commit()
session_form = ClassForm()
return render_template(
'main/user_page.html',
current_user=current_user,
school_form=school_form,
class_form=class_form,
session_form=session_form,
school_list=school_list
)
except Exception as e:
return Response(repr(e), status=HTTPStatus.BAD_REQUEST)
The curious part is that this was working at the beginning of 2022. I was pulled onto another project and have recently been put back on this one. I updated all dependencies and am not seeing any errors.
I am not sure what to check at this point.
Ideas?
When I click submit in the add tasks page, I get no response. The submit button is supposed to add tasks to the list in the tasks page. It does not show any errors and I'm not sure if its code is even running.
views.py:
from django.shortcuts import render
from django import forms
from django.urls import reverse
from django.http import HttpResponseRedirect
# Create your views here.
class NewTaskForm(forms.Form):
task = forms.CharField(label="New Task")
# Add a new task:
def index(request):
# Check if there already exists a "tasks" key in our session
if "tasks" not in request.session:
# If not, create a new list
request.session["tasks"] = []
return render(request, "tasks/index.html", {
"tasks": request.session["tasks"]
})
def add(request):
# Check if method is POST
if request.method == "POST":
# Take in the data the user submitted and save it as form
form = NewTaskForm(request.POST)
# Check if form data is valid (server-side)
if form.is_valid():
# Isolate the task from the 'cleaned' version of form data
task = form.cleaned_data["task"]
# Add the new task to our list of tasks
request.session["tasks"] += [task]
# Redirect user to list of tasks
return HttpResponseRedirect(reverse("tasks:index"))
else:
# If the form is invalid, re-render the page with existing information.
return render(request, "tasks/add.html", {
"form": form
})
return render(request, "tasks/add.html", {
"form": NewTaskForm()
})
add.html template:
{% extends "tasks/layout.html" %}
{% block body %}
<h1>Add Task:</h1>
<form action="{% url 'tasks:add' %}" method="post"></form>
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
View Tasks
{% endblock %}
index.html:
***
{% extends "tasks/layout.html" %}
{% block body %}
<h1>Tasks:</h1>
<ul>
{% for task in tasks %}
<li>{{ task }}</li>
{% empty %}
<li>No tasks</li>
{% endfor %}
</ul>
Add a New Task
{% endblock %}
***
Your form element is closed out prematurely, so clicking the input probably doesn't do anything at all. If it somehow does, because you still have a closing </form> tag then it doesn't know where to send the POST to.
<form action="{% url 'tasks:add' %}" method="post"></form> <-- This
I have a simple form in my template, index.html:
{% if stripped_thumbnail_file_list %}
{% for thumbnail_name in stripped_thumbnail_file_list %}
<div class="">
<div class="">
This is my form
<form class="" action="{% url 'index' %}" method="post">
{% csrf_token %}
<input type="image" value="{{ thumbnail_name }}" src="{{ MEDIA_URL}}thumbnails/{{ thumbnail_name }}.jpg">
</form>
</div>
</div>
{% endfor %}
{% else %}
<p>No videos are available.</p>
{% endif %}
I want the index view to pull the {{ thumbnail_name }} value from this form and use it as a variable when the index view redirects to a different view that will use that name to play a matching video.
I have been unsuccessful in trying to pull that value from the form as I have it. I suspect this may because I'm not creating a Django form object. I tried to create that object, but I can't find any examples of a Django form object as an image like I have in my form.
What should that look like? Or, can someone make a recommendation on how to pull the value from the form as is?
EDIT: adding views.py snippet:
def index(request):
# if this is a POST request we need to process the form data
if request.POST:
# get thumbnail_name from form
# redirect to a new URL (hardcode thumbnail name for now):
return HttpResponseRedirect('2017-02-01_04-29-10/video/')
thumbnail_file_list = get_file_list(target_directory, ".jpg")
stripped_thumbnail_file_list = strip_file_extension(thumbnail_file_list)
template = loader.get_template('dash/index.html')
context = {
'stripped_thumbnail_file_list': stripped_thumbnail_file_list,
}
return HttpResponse(template.render(context, request))
def video(request, file_name):
print("this is the file name passed: " + file_name)
template = loader.get_template('dash/video.html')
context = {
'file_name': file_name,
}
return HttpResponse(template.render(context, request))
First: you need to declare the 'name' attribute on your form imput.
<input name="thumbnail_name" type="image" value="{{ thumbnail_name }}" src="{{ MEDIA_URL}}thumbnails/{{ thumbnail_name }}.jpg">
Second: Why don't you just set the 'action' of the form to your 'video' function (when you perform a redirect, you are losing all your POST data).Then, from there you could retrieve the value: something like that
def video(request):
file_name = request.POST.get('thumbnail_name')
print("this is the file name passed: " + file_name)
template = loader.get_template('dash/video.html')
context = {
'file_name': file_name,
}
return HttpResponse(template.render(context, request))
Hope it helps
I'm trying to set up a user profile where you can enter skills. Entering the skills and save them in the databse already works. Now I want to give the user the opportunity to delete every single one of them with a button click. I tried posting the ID of each skill on button click in the URL and read it out in my view to get the item and delete it, but that does not work like I thought and I cant find out why...
MY VIEW
def profile_settings(request, id=None):
# get logged in user object from session
user_id = request.user.id
# get related userprofile
userprofile = UserProfile.objects.get(pk=user_id)
# get all skills of the userprofile
user_skills = Skill.objects.filter(user=userprofile)
if request.method == 'POST':
form = SkillForm(request.POST)
if 'delete-skill' in request.POST:
if id:
print(id)
skill = Skill.objects.get(pk=id).delete()
elif 'add-skill' in request.POST:
if form.is_valid():
# get data from form
name = form.cleaned_data['name']
category = form.cleaned_data['category']
rating = form.cleaned_data['rating']
# create new skill object for a user
new_skill = Skill(name=name, category=category, rating=rating, user=userprofile)
# save it in the database
new_skill.save()
else:
form = SkillForm()
return render(request, 'profile-settings.html', {'skillform': form, 'existing_skills': user_skills})
MY URLS
urlpatterns = [
url(r'^landing', views.landing, name='landing'),
url(r'^neuigkeiten', views.news, name='news'),
url(r'^profileinstellungen/', views.profile_settings, name='profileinstellungen'),
url(r'^profileinstellungen/(?P<id>\d+)/$', views.profile_settings, name='profileinstellungen'),
]
MY TEMPLATE
{% extends 'base.html' %}
{% block content %}
<form method="post" style="margin-top: 300px">
{% csrf_token %}
{{ skillform }}
<input type="submit" value="Hinzufügen" name="add-skill "/>
</form>
<form method="post">
{% csrf_token %}
<ul>
{% for skill in existing_skills %}
<li>{{ skill.name }}</li>
<input href="{% url 'profileinstellungen' id=skill.id%}" type="submit" value="Löschen" name="delete-skill"/>
{% endfor %}
</ul>
</form>
{% endblock %}
It does not post the ID of the skill in the URL. Is there an alternative approach?
Try to change this :
<input href="{% url 'profileinstellungen' id=skill.id%}" type="submit" value="Löschen" name="delete-skill"/>
by this :
<input href="{% url 'profileinstellungen' %}{{skill.id}}" type="submit" value="Löschen" name="delete-skill"/>
because the "url" will know automatically that "skill.id" was related to "id"
You have forgotten to include dollar signs at the end of the regexes in your URL patterns. It should be:
urlpatterns = [
url(r'^landing$', views.landing, name='landing'),
url(r'^neuigkeiten$', views.news, name='news'),
url(r'^profileinstellungen/$', views.profile_settings, name='profileinstellungen'),
url(r'^profileinstellungen/(?P<id>\d+)/$', views.profile_settings, name='profileinstellungen'),
]
In particular, the problem is the regex r'^profileinstellungen/. Without the dollar, it matches URLs like /profileinstellungen/4/, so the id is not passed to the view.
Secondly, it doesn't make sense to give the input an href attribute. Each input should be in a separate form, and you can set the form action to the URL you wish to submit the post request to.
<ul>
{% for skill in existing_skills %}
<form method="post" action="{% url 'profileinstellungen' id=skill.id%}">
{% csrf_token %}
<li>
{{ skill.name }}
<input type="submit" value="Löschen" name="delete-skill"/>
</li>
</form>
{% endfor %}
</ul>
I have models:
class MediaInfo(models.Model):
title = models.CharField(max_length=50,blank=True)
description = models.CharField(max_length=255,blank=True)
media_file = models.FileField(upload_to=get_upload_file_name)
def __unicode__(self):
return self.title
class Media(models.Model):
media_files = models.ForeignKey(MediaInfo) # I want ManyToManyField but it gives error saying no ForeignKey relation
Here I used Inline Formset to select multiple file.
What I wanted was I wanted a browser button on template and when I click that I could select multiple file or images with all those title and description informations.
For this I wrote a view:
def MediaAddView(request):
MediaInlineFormset = inlineformset_factory(MediaInfo, Media)
if request.method == "POST":
formset = MediaInlineFormset(request.POST, request.FILES)
if formset.is_valid():
formset.save()
return HttpResponseRedirect("someurl")
else:
return render_to_response("media_add.html", {"formset":formset,})
else:
formset = MediaInlineFormset()
return render_to_response("media_add.html", {"formset":formset,})
and my template media_add.html
{% block content %}
<form method="post" action="" enctype="multipart/form-data">{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{form.id}}
<ul>
<li>{{form.media_file}}</li>
</ul>
{% endfor %}
<input type="submit" value="Submit" />
</form>
{% endblock %}
When I do this in my template I see nothing just 3 dots of list (li).
Like I said I wanted a browse button and when I click it I wanted to select and upload multiple files.
Whats wrong in here ? Can anyone guide me ?