I have a create document form which has only two fields first, title second, a foreign key to Note model.
Now i want to make the document title unique so i used;
title = models.CharField(max_length=32, default='document-title', unique=True)
Well it works! but it doesnt show any feedback that new Document couldnt created…
here is the documentation i tried to follow: https://docs.djangoproject.com/en/4.2/topics/forms/modelforms/#considerations-regarding-model-s-error-messages
forms.py
from django import forms
from django.forms import ModelForm
from .models import Document
class DocumentForm(ModelForm):
class Meta:
model = Document
fields = {'title',}
labels = {'title': '',}
widgets = {'title': forms.TextInput(attrs={'placeholder': 'document_title'}),}
error_messages = {
NON_FIELD_ERRORS: {
"unique_together": "model name is not unique.",
}
}
views.py
def home(request):
if request.method == 'POST':
form = DocumentForm(request.POST)
if form.is_valid():
document = form.save()
dummy_note = Note.objects.create(document=document)
return HttpResponseRedirect('/note')
form = DocumentForm
documents = Document.objects.all()
return render(request, 'note/home.html', {'form': form, 'documents': documents})
home.html
{% extends 'base.html' %}
{% block content %}
<div class="container d-flex flex-column">
<center class="p-3">
Note App Home Page!
</center>
<div class="d-flex justify-content-between">
<div class="card m-5" style="width: 20em;">
<div class="card-header">
Create Document
</div>
<div class="card-body">
<form method=POST>
{% csrf_token %}
{{form.as_p}}
<button name="create_document" type="submit" class="btn btn-primary">Create</button>
</form>
</div>
</div>
<div class="card m-5" style="width: 20em;">
<ul class="list-group list-group-flush">
<!-- <li class="list-group-item">An item</li> -->
{% for document in documents %}
<li class="list-group-item">
<a href="{% url 'document-page' document.title %}">{{document.title}}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
i tought it would display a message right next to the input field but it doesnt show anything…
I want to have a display under/next to the input field how can i do it?
>Solution :
You should not create a new form in case the POST request is invalid, so constructing a new form should be done in the else
clause in case of a GET request (method is not POST
):
def home(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
dummy_note = Note.objects.create(document=form.save())
return HttpResponseRedirect('/note')
else:
form = DocumentForm()
documents = Document.objects.all()
return render(
request, 'note/home.html', {'form': form, 'documents': documents}
)
As for the error message, this is not a unique_together
: the uniqness is defined on the title
field, so you can override the error message with:
class DocumentForm(ModelForm):
class Meta:
model = Document
fields = {
'title',
}
labels = {
'title': '',
}
widgets = {
'title': forms.TextInput(attrs={'placeholder': 'document_title'}),
}
error_messages = {
'title': {
'unique': 'model name is not unique.',
}
}
Note: While most forms do not process media files, it is probably better to pass
request.FILES
[Django-doc] to the form anyway, such that if you later add an extra media field, all views that use the form will indeed handle the files properly.