Django url not found upon submitting form - python

My apologies if the question is stupid, I am a newbie to this. I am creating a django web application. I have created a form inside it. When I submit the form, it says 'url' not found even though the same URL loads fine for the first time when opening the form. This is whats confusing me. Here is my code:
#forms.py
class Recipe_ruleForm(forms.ModelForm):
class Meta:
model = Recipe_rule
fields = ('content',)
#urls.py
url(r"^create_recipe_rule/(?P<recipe_pk>[0-9]+)/$",views.create_recipe_rule, name="create_recipe_rule"),
#views.py
def create_recipe_rule(request, recipe_pk):
form = Knowledgebase_ruleForm
selected_recipe = Recipe.objects.get(pk = recipe_pk)
if request.method == 'POST':
form = Recipe_ruleForm(request.POST)
if form.is_valid():
#current_user = request.user
data = form.cleaned_data
recipe_rule_data=Recipe_rule.objects.create(recipe=selected_recipe, content=data['content'])
recipe_rule_data.save()
recipe_rule = Recipe_rule.objects.get(pk = recipe_rule_data.pk)
recipe=selected_recipe
recipe = Recipe.objects.get(pk = recipe.pk)
return redirect('recipe_detail', pk=recipe.pk)
else:
messages.error(request, "Error")
return render(request, 'create_recipe_rule.html' , {'form': form})
Here is the error when I submit the form:
Page not found (404) Request Method: POST Request
URL: http://[ip_adress]:[port]/create_recipe_rule/
UPDATE:
Here is my template:
{% extends "account/base.html" %}
{% load i18n %}
{% load bootstrap %}
{% block body_class %}applications{% endblock %}
{% block head_title %}{% trans "Create recipe" %}{% endblock %}
{% block body %}
<form action="/create_recipe_rule/" method="post">
{% csrf_token %}
<div class="form-group">
<label for="{{ form.content.label }}">{{ form.content.label }}:</label>
<textarea type="{{ form.content.type }}" name="{{ form.content.name }}" max_length="500" class="form-control" id="{{ form.content.id }}"></textarea>
</div>
<input class="btn btn-default" type="submit" value="submit">
</form>
{% endblock %}

You have action="/create_recipe_rule/", which is missing the recipe id.
One option is to simply remove the action from the form, then your browser will submit the request to the current url.
<form method="post">
If you do want to include the form action, then first you need to update your view so that it includes the recipe id in the template context.
return render(request, 'create_recipe_rule.html' , {'form': form, recipe_id: recipe_id })
Then you can update the form action to include the recipe id.
action="/create_recipe_rule/{{ recipe_id }}"
It's good practice to use the {% url %} tag, so that you are not hardcoding urls in the template:
action="{% url 'create_recipe_rule' recipe_id %}"

Related

Form fields not displaying when creating a simple form with mongoengine-flask with wtf forms

I'm trying to get just a basic model and form to show up with mongoengine and WTF forms, and following the basic instructions from the website aren't working for me. I'm sure it's something simple that is missing, but I've never used flask, mongoengine, or WTFforms, so I'm sort of
Here is my schema definition in models.seed
class PlandoSeed(db.Document):
def __init__(self, preset:str='open', num_players:int=2, num_plants:int=1, **entries: dict):
self.__dict__.update(entries)
self.preset = preset
self.num_players = num_players
self.num_plants = num_plants
preset: db.StringField()
num_players: db.IntField(min=2, max=6)
num_plants: db.IntField(min=1, max=6)
seeds :List[PlandoSeed] = [PlandoSeed('standard',2,2), PlandoSeed('open',4,1), PlandoSeed()]
PlandoSeedForm = model_form(PlandoSeed)
Then this is the route/view that I created in views.py:
#app.route('/seeds/create', methods = ['GET', 'POST'])
def create_seed():
form = PlandoSeedForm(request.form)
if request.method == 'POST' and form.validate():
# todo
redirect('/seeds/')
return render_template('new_seed.jinja', form=form)
Finally, this is my 'new_seed.jinja' template:
{% extends 'base.jinja' %}
{% block content %}
<h1>{% block title %} Create Seed {% endblock %}</h1>
<form method="POST" action="/seeds/create/">
{{ form.csrf_token }}
{% for field in form %}
{{ field }}
{% endfor %}
<input type="Submit" value="Go">
</form>
{% endblock %}
My expectation is that the Create Seed page will have a form with the default input for a text field and integer fields. However, the only field that is in the form object in the jinja template is the CSRF token.Here is what it looks like.
And this is the generated HTML for the form:
<h1> Create Seed </h1>
<form method="POST" action="/seeds/create/">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input type="Submit" value="Go">
</form>

Getting a "NoReverseMatch" error in python code

Getting this error in my python code when attempting to delete a created topic.
Here are the url, views, and template snippets.
path('delete_topic/<int:topic_id>/', views.delete_topic, name='delete_topic')
def delete_topic(request, topic_id):
topic = Topic.objects.get(id=topic_id)
if request.method == 'POST':
topic.delete()`enter code here`
return redirect('online_diaries:topics', topic_id=topic.id)
context = {'topic': topic}
return render(request, 'online_diaries/delete_topic.html', context)
{% extends "online_diaries/base.html" %}
{% block content %}
<p>Are you sure to delete the topic <b><u>{{ topic }}?</b></u></p>
<form method="POST" action = "{% url 'online_diaries:delete_topic' topic.id %}">
{% csrf_token %}
cancel
<input type = "submit" name = "Confirm" class="btn btn-secondary btn-sm">
</form>
{% endblock content %}

Post data from button value to views in Django

I have a button in my template and I need to post the value of the button to my views. Unfortunately, my request.POST returns 'None'. How can I retrieve the information from my HTML template?
Thank you.
My template:
{% extends 'vocab/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form action="{% url 'card' %}" method="POST">
{% for document in documents %}
<button type ='submit' value="{{ document.file }}" class='btn btn-outline-info' >
{{document.file}} </button>
{% endfor %}
</form>
{% endblock content %}
My view:
def card_view(request):
if request.method == 'POST':
context = {'request.POST':request.POST}
return render(request, 'vocab/card.html', context)
add name as attribute in button. name is like Key in python dictionary while value is the value of the Key.
Therefore, by using name you can obtain the ```value``
context = {'request.POST' : request.POST['name']}

Reverse for 'edit_team' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['club_home/edit_team/(?P<pk>[0-9]+)/$']

Receiving the above error when trying to create a page to update my model using a serializer. Unable to use pk in edit_team view. Any ideas where I am going wrong? Delete button is working fine with the pk not sure why the update is not.
urls.py
path('teams/', views.TeamInfo.as_view(), name='teams'),
path('delete_team/<int:pk>/', views.delete_team, name='delete_team'),
path('edit_team/<int:pk>/', views.edit_team, name='edit_team'),
teams.html
<div class="team">
<h3>Team Details</h3>
<p>
{% csrf_token %}
{% for info in teams %}
<li>{{ info.club_id }}</li>
<li>{{ info.team_name }}</li>
<li>{{ info.manager_name }}</li>
<form action="{% url 'clubs:delete_team' info.pk %}">
<input type="submit" value="Delete">
</form>
<form action="{% url 'clubs:edit_team' info.pk %}">
<input type="submit" value="Edit">
edit_team.html
{% extends 'club_main_page.html' %}
{% load rest_framework %}
{% load staticfiles %}
{% block body_block %}
<div class="editteam">
<h3>Edit Team</h3>
<form action="{% url 'clubs:edit_team' pk=instance.pk %}" method="POST">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" name="" value="Update">
</form>
</div>
{% endblock %}
views.py
def delete_team(request, pk):
team = Team.objects.filter(pk=pk)
team.delete()
return redirect('clubs:teams')
def edit_team(request, pk):
instance = Team.objects.filter(pk=pk)
if request.method == 'POST':
serializer = TeamSerializer(request.POST, instance=instance)
if serializer.is_valid():
serializer.save()
return redirect('/')
else:
return redirect('/')
else:
serializer = TeamSerializer(instance=instance)
return render(request, 'edit_team.html', {'serializer': serializer})
Trackback: \clubkit\clubs\views.py in edit_pitch
return render(request, 'edit_pitch.html', {'serializer': serializer})
In your template you write:
<form action="{% url 'clubs:edit_team' pk=instance.pk %}" method="POST">
but there is no instance variable, you pass to the rendering process, you thus should add this one as well, so:
def edit_team(request, pk):
instance = Team.objects.filter(pk=pk)
if request.method == 'POST':
serializer = TeamSerializer(request.POST, instance=instance)
if serializer.is_valid():
serializer.save()
return redirect('/')
else:
return redirect('/')
else:
serializer = TeamSerializer(instance=instance)
return render(
request,
'edit_team.html',
{'serializer': serializer, 'instance': instance})
I'm not sure however, if redirecting to / is a good idea, certainly not if the serializer is not valid. In that case, one typically wants to render the page again, but with the errors. Therefore it is probably also a better idea to make use of forms [Django-doc].
You didn't pass the PK to the template, so it can't be used to generate the URL there. Change the last line of your view:
return render(request, 'edit_team.html', {''pk': pk, serializer': serializer})
Would have liken to figure this out using the serializer. But just went with a form here solution just in case any one needs it:
def edit_team(request, pk):
instance = Team.objects.filter(pk=pk).first()
if request.method == 'POST':
form = TeamForm(request.POST, instance=instance)
if form.is_valid():
form.save()
return redirect('clubs:teams')
else:
return redirect('clubs:teams')
else:
form = TeamForm(instance=instance)
return render(request, 'edit_team.html', {'form': form,
'instance': instance})
Then in the template:
{% extends 'club_main_page.html' %}
{% block head %}
<title>Edit Pitch</title>
{% endblock %}
{% block body_block %}
<div class="container">
<form method="post">
{% csrf_token %}
{{ form.as_p}}
<button type="submit">Submit</button>
</form>
</div>
{% endblock %}

Reverse for 'favorite' with arguments '('',)' not found, following Bucky's Django tutorial on YouTube

I keep getting NoReverseMatch at /music/2/ error, and it's pointing me to the parent template that i'm inheriting from, base.html, but i can't find anything wrong with it. I know it's probably annoying when someone asks you to search for errors, but maybe someone can easily see what i'm unable to see
{% extends "music/base.html" %}
{% block content %}
<p> Album : {{one_album}} </p>
<p> Song list : </p>
{% if somethings_wrong %}
<p> {{ somethings_wrong }} </p>
{% endif %}
<form action = "{% url 'music:favorite' album.id %}" method="post" >
{% csrf_token %}
{% for song in album_entries %}
<input type="radio" id="song{{forloop.counter}}" name="song" value="{{ song.id }}">
<label for="song{{ forloop.counter }}">
{{ song.song_title }}
{% if song.is_favorite %} #afterwards, set this explicitly to true, for learning purposes
<img src="https://i.imgur.com/olM72b8.png"/> #check if this slash is necessary later
{% endif %}
</label><br>
{% endfor %}
<input type="submit" value="Favorite">
</form>
{% endblock content %}
Here's the base.html
<p>
Link to the homepage
</p>
{% block content %}
{% endblock content %}
Here's the Views.py :
from django.shortcuts import render
from django.http import HttpResponse
from .models import Album, Song
def index(request):
albums = Album.objects.all()
context = {'albums': albums}
return render(request, 'music/index.html', context)
def detail(request, album_id):
# show album and every entry in that album.
one_album = Album.objects.get(id=album_id)
album_entries = one_album.song_set.all()
context = {'one_album' : one_album, 'album_entries' : album_entries}
return render(request, "music/album.html", context)
# Create your views here.
def favorite(request, album_id):
one_album = Album.objects.get(id=album_id)
try:
context = {'one_album' : one_album}
selected_song = one_album.song_set.get(id=request.POST["song"])
except(KeyError, Song.DoesNotExist):
somethings_wrong = "Something's not right with your choice"
context = {'one_album' : one_album, 'somethings_wrong' : somethings_wrong}
return render(request, "music/album.html", context)
else:
selected_song.is_favorite = True
selected_song.save()
return render(request, "music/album.html", context)
i think error is somewhere here, urls.py and models.py are pretty simple. I've added is_favorite booleanfield to Song class, which is False by default, and urls.py is pretty straightforward
path('<int:album_id>/favorite', views.favorite, name='favorite')
variable that you want to refer to is one_album
but you are calling it album.
change
<form action = "{% url 'music:favorite' album.id %}" method="post" >
to
<form action = "{% url 'music:favorite' one_album.id %}" method="post" >

Categories

Resources