django project_form is not valid? - python

I have been trying to implement a way to post a project post where the user can upload multiple images. The multiple image upload works but posting the post itself does not work.
I am not sure what to do with the project_form.
It is not valid even tho the fields have correct values.
My code is:
views.py
class CreateProjectsView(View):
def get(self, request):
p_photos = P_Images.objects.all()
#project_form = ProjectsForm(initial=self.initial)
project_form = ProjectsForm
context = {
'p_photos': p_photos,
'project_form': project_form,
}
return render(self.request, 'projects/forms.html', context)
def post(self, request):
project_form = ProjectsForm(request.POST or None, request.FILES or None)
p_formset = P_ImageForm(request.POST, request.FILES)
# Checks if the project_form is valid before save
if project_form.is_valid():
instance = project_form.save(commit=False)
instance.user = request.user
instance.save()
# Checks if multiple image upload is valid before save
if p_formset.is_valid():
#if project_form.is_valid() and p_formset.is_valid():
#instance = project_form.save(commit=False)
#instance.user = request.user
#instance.save()
images = p_formset.save(commit=False)
images.save()
data = {
'is_valid': True,
'name': images.p_file.name,
'url': images.p_file.url
}
else:
data = {
'is_valid': False,
}
return JsonResponse(data)
forms.html
<form action="{% url 'create_post:retrieve_projects' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in project_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in project_form %}
{{ field.errors }}
{{ field }} <br />
{% endfor %}
<input type="submit" value="OK">
</form>

If the form is not valid, you should provide a way for the user to correct their errors and resubmit the form. Perhaps something like this:
if project_form.is_valid():
instance = project_form.save(commit=False)
instance.user = request.user
instance.save()
else:
return render(request, 'project_form.html', {'form': project_form})

So I actually found a fix for this.
The issue is in the forms.html
I changed the "create_post:retrieve_projects" to "create_post:create_projects" in my form section.
forms.html
<form action="{% url 'create_post:create_projects' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in project_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in project_form %}
{{ field.errors }}
{{ field }} <br />
{% endfor %}
<input type="submit" value="OK">
</form>

Related

Django form only sending GET requests

I have this add page which uses a django form to get information which i am trying to store within "tasks" list and display in the todo html page.
i believe all my syntax is correct but it is not displaying the list of tasks when I submit the form.
on cmd it detects a GET request every time i submit the form, shouldnt it be saying post?
views:
from django.shortcuts import render
from django import forms
tasks = []
class newTaskForm(forms.Form):
task = forms.CharField(label="new task")
# Create your views here.
def index(request):
return render(request, "tasks/todo.html", {
"tasks": tasks
})
def add(request):
if request.method == "POST":
form = newTaskForm(request.POST)
if form.is_valid():
task = form.cleaned_data["task"]
tasks.append(task)
else:
return render(request, "tasks/add.html", {
"form": form
})
return render(request, "tasks/add.html", {
"form": newTaskForm
})
add:
{% extends "tasks/layout.html" %}
{% block body %}
<form action="{% url 'tasks:add' %}">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
Veiw list
{% endblock %}
todo:
{% extends "tasks/layout.html" %}
{% block body %}
<h1> To Do List</h1>
<ul>
{% for task in tasks %}
<li> {{ task }}</li>
{% endfor %}
</ul>
Add items
{% endblock %}
as #Iain Shelvington suggested, you need to put method="post" as
{% block body %}
<form method="post" action="{% url 'tasks:add' %}">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
Veiw list
{% endblock %}

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 %}

Python Django forms, form is not work with entered data

Im new with Django and Im trying to include my own form
My forms.py
class MyOwnForm(forms.ModelForm):
class Meta:
model = Album
fields = ['username']
My views.py
def testing_Form(request):
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
username = form.cleaned_data['username']
return render(request, 'form.html', {'form': form})
my form.html
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
and the last one form_template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2" >{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
When I open the Form Webpage, I get a empty entry field and the submit button. But when I click this button. The page is reloading and nothing more.
what do i have to do that i can work with the entered data?
But when I click this button. The page is reloading and nothing more.
Because of this, I'm assuming that you intend to show some information after the form is submitted. Here's a simple example that just displays an acknowledgement after the form is submitted.
{% if submitted %}
<div class="jumbotron contactainer">
<h1 class="display-4">Submitted</h1>
<hr class="my-4">
<p class="lead">{{ username }}'s album has been submitted</p>
</div>
{% else %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'form_template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
{% endif %}
views.py
def testing_Form(request):
submit = False
if not request.user.is_authenticated:
return render(request, 'login.html')
else:
form = MyOwnForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.username = request.user
album.save()
submit = True
username = form.cleaned_data['username']
return render(request, 'form.html', {'username':username, 'submitted':submit})
else:
return render(request, 'form.html', {'form': form, 'submitted':submit})
You can do anything you wish with the username variable or add new variables, just remember to add them to the context dictionary if you wish to display them. The submit variable I've added is used in the template to determine what to show. Hope this helps :)
Not quite sure what you are exactly trying to achieve. However if you want to show the value of your previous submit on your screen for example as: Previous submitted username: <input username>, you can use the defined form in your template, including the values if there was a submit before.
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
You can always add extra context to your template by assigning it to the context dictionary in the similar way you did with the {'form': form} as {'form': form, 'hello': "My hello string"} in your view.
In your template you could now use {{ hello }} as an variable.
Note that you are also using commit=False in your form to add more request data to the model after (user). Currently you left it in the unsaved state. To save the new form entry, you need to call album.save() after the modifications.
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.save() # now commit
The username = form.cleaned_data['username'] has been defined, but never been used. Which with the example above is no longer required.
You can fetch the album objects when the user is authenticated and pass them to the template to work with as context like:
(bad practice style, but just to give you an idea within the scope of your code)
if request.user.is_authenticated:
return render(request, 'login.html')
else:
form = AlbumForm(request.POST or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
albums = Album.objects.all()
return render(request, 'formhandle/form.html', {'form': form, 'albums': albums})
Which you could show in your form template as:
{% if form.username.value %}
Previous submitted username: {{ form.username.value }}
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{# ... all as it was ... #}
</form>
<ul>
{% for album in albums %}
<li>{{ album.user.username }}</li>
{% endfor %}
</ul>

Inputs are not showing in django form

My form inputs are not showing. It's just a button. i think homepage.html doesn't getting this form
Forms.py
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
Views.py
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'mainApp/homepage.html', {'form': form})
homepage.html
{% extends "mainApp/wrapper.html" %}
{% block title %}Главная{% endblock %}
{% block content %}
<h1>Main page</h1>
{% include "mainApp/includes/somehtml.html" %}
<br>
<form action="/account/username/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<br>
{% endblock %}
It shoes only "Submit" button. How can I fix it?
Please change
{{form}}
to {{form.as_p}}
Views.py
from app_name.forms import * # Change app_name with your app name
def get_name(request):
temp_context = {} # Check here
if request.method == 'POST':
acc_form = NameForm(request.POST) # Check here
temp_context["acc_form"] = acc_form # Check here
if acc_form.is_valid(): # Check here
return HttpResponseRedirect('/')
else:
temp_context[“acc_form”] = NameForm() # Check here
return render(request, 'mainApp/homepage.html', temp_context) # Check here
homepage.html
{% extends "mainApp/wrapper.html" %}
{% block title %}Главная{% endblock %}
{% block content %}
<h1>Main page</h1>
{% include "mainApp/includes/somehtml.html" %}
<br>
<form action="/account/username/" method="post">
{% csrf_token %}
{{ acc_form }} # Check here;
# you can also try {{ acc_form.as_table }} or {{ acc_form.as_p }} if there any issue
<input type="submit" value="Submit" />
</form>
<br>
{% endblock %}

Django url not found upon submitting form

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 %}"

Categories

Resources