I've just started my first app with Django by following a video on YouTube. The app is a students dashboard with 8 tools and features to help the student to make note, search for help, save books, etc.
When I follow the steps I get stuck in the creation of a new note but note from the admin side but from the actual notes template that has a crispy form and a create button. The program is supposed for writing a title and description (the content of the note) and then press the create button. When I try to click, nothing is happening.
#This is the view.py page in the dashboard app :
from django.shortcuts import render
from . forms import *
from django.contrib import messages
# Create your views here.
def home(request):
return render(request, 'dashboard/home.html')
def notes(request):
if request.method == "POST":
form = NotesForm(request.POST)
if form.is_valid():
notes = Notes(user=request.user,title=request.POST['title'],description=request.POST['description'])
notes.save()
messages.success(request,f"Notes Added from {request.user.username} Successfully")
else:
form = NotesForm()
notes = Notes.objects.filter(user=request.user)
context = {'notes':notes,'form':form}
return render(request,'dashboard/notes.html',context)
and this is the notes.html page in the dashboard app > template folder > dashboard folder :
{% extends 'dashboard/base.html' %}
<!-- Load the static files here -->
{% load static %} {% load crispy_forms_tags %}
<!-- loading the crispy files must be here so now i write anything to
create some space and lines here we go baby lets add more -->
{% block content %}
<div >
<div >
{% for note in notes %}
<div >
<a href="#">
<div >
<div >{{note.title}}</div>
<div >{{note.description|slice:"0:100"}}</div>
<div >
<a href="#"> <i ></i></a>
</div>
</div>
</a>
</div>
{% endfor %}
<br /><br />
</div>
</div>
<br /><br />
<div >
<form method="POST">
{% csrf_token %}
<fieldset >
<legend >Create Notes</legend>
</fieldset>
{% crispy form %}
<div >
<button href="" type="submit">Create</button>
</div>
</form>
</div>
{% endblock content %}
so, this the models.py file too
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Notes(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField()
def __str__(self):
return self.title
class Meta:
verbose_name = "notes"
verbose_name_plural = "notes"
in case the problem is not here, please take a look on the inside this forms.py
from dataclasses import fields
from django import forms
from . models import *
class NotesForm(forms.ModelForm):
class Meta:
model = Notes
fields = ['title', 'description']
and .. urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.home, name='home'),
path('notes',views.notes, name="notes")
]
CodePudding user response:
There are many minor mistakes in the code:
It is
{{form|crispy}}
to display the form not{% crispy form %}
.You are also not using
HttpResponseRedirect
[django-doc] for redirecting, after saving form fromPOST
data, you should always return anHttpResponse
, its a good practice.
Try below code:
Notes.html
{% block content %}
{% load crispy_forms_tags %}
<div >
<div >
{% for note in notes %}
<div >
<a href="#">
<div >
<div >{{note.title}}</div>
<div >{{note.description|slice:"0:100"}}</div>
<div >
<a href="#"> <i ></i></a>
</div>
</div>
</a>
</div>
{% endfor %}
<br /><br />
</div>
</div>
<br /><br />
<div >
<form method="POST" action="{% url 'notes' %}" novalidate>
{% csrf_token %}
<fieldset >
<legend >Create Notes</legend>
</fieldset>
{{form|crispy}}
<input type="submit" value="Create">
</form>
</div>
{% endblock content %}
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.shortcuts import render
from . forms import *
from django.contrib import messages
from django.urls import reverse
def home(request):
return render(request, 'dashboard/home.html')
def notes(request):
if request.method == "POST":
form = NotesForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
descrip = form.cleaned_data['description']
notes = Notes(
user=request.user, title=title, description=descrip)
notes.save()
messages.success(
request, f"Notes Added from {request.user.username} Successfully")
return HttpResponseRedirect(reverse('thanks'))
else:
form = NotesForm()
notes = Notes.objects.filter(user=request.user)
context = {'notes': notes, 'form': form}
return render(request, 'dashboard/notes.html', context)
def thanks(request):
return render(request, 'dashboard/thanks.html')
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('notes/', views.notes, name="notes"),
path('thanks/', views.thanks, name='thanks')
]
thanks.html
<body>
<h2>The form successfully submitted</h2>
</body>
Your forms.py
can be remain same as it is.
CodePudding user response:
Are you sure nothing is happening when you submit the form? Maybe nothing is being displayed in the page, because you are just rendering the page again, this time with the request.POST data in the form, so it probably looks like nothing happened. @Sunderam Dubey is correct about the redirect, it follows the Post/Redirect/Get pattern, which is a one you should use to handle forms. There is another pattern that might help doing all this easier:
from django.shortcuts import redirect
def notes(request):
# When a POST request is made (a form is submitted), the form will
# have the data in it, otherwise, it will be empty. No need therefore
# for checking if request.method == 'POST'
form = NotesForm(request.POST or None)
if form.is_valid():
# Step 1, save the form with commit=False, so that data can be added
# before the actual save. Here you can add the user to the form data
# since that is needed, but was not in the form submitted
note = form.save(commit=False)
# Add the user to the note
note.user = request.user
# Finally, save the note
note.save()
messages.success(request,f"Notes Added from {request.user.username} Successfully")
# MOST importantlly - REDIRECT. I prefer the shortcut redirect
# which can be imported with from django.shortcuts import redirect
return redirect("notes")
notes = Notes.objects.filter(user=request.user)
context = {'notes':notes,'form':form}
return render(request,'dashboard/notes.html',context)