Django Model form not rendering - python

Im trying to create a model form on django but it doesnt want to render even though I mapped it properly and created the path.
models.py
from django.db import models
# Create your models here.
Media_Choices = (
("TV", "TV"),
("Radio", "Radio"),
("Youtube", "Youtube"),
("Podcast", "Podcast"),
)
class Appear(models.Model):
Show = models.CharField(max_length=100)
Media = models.CharField(max_length=30, blank=True, null=True, choices=Media_Choices)
Episode = models.IntegerField()
Date = models.DateField(max_length=100)
Time = models.TimeField(auto_now=False, auto_now_add=False)
Producer = models.CharField(max_length=100)
Producer_Email = models.EmailField(max_length=254)
def __unicode__(self):
return self.Show + ' ' + self.Producer_Email
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Appear
class AppsForm(ModelForm):
class Meta:
model = Appear
fields = '__all__'
def clean_Producer_Email(self):
Producer_Email = self.cleaned_data.get('Producer_Email')
if (Producer_Email == ""):
raise forms.ValidationError('field cannot be left empty')
for instance in Appear.objects.all():
if instance.Producer_Email == Producer_Email:
raise forms.ValidationError('Please fill in correct email')
return Producer_Emailenter
views.py
from django.shortcuts import render
from .forms import AppsForm
# Create your views here.
def AppS(request):
form = AppsForm()
context = {'forms': form}
return render(request, 'AppsForm.html', context)
it refuse to render but it displays the html tag that is in the file but not the fields from the form. this is the html template
AppsForm.html
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="submit">
</form>
{% endblock %}

you view is wrong try this
def AppS(request):
if request.method == 'POST':
form = AppsForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
form = AppsForm()
return render(request, 'AppsForm.html', {'form': form})
and in your html
<form method="POST" class="" action="">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" class="" value="Submit">
</form>
now you are good to go and tell me if you still get error

Based on your AppS() function, where you are passing the form as 'forms' to your AppsForm.html you can render it with crispy_forms like:
AppsForm.html:
{% extends 'your_app/base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<form method="POST" class="" action="">
{% csrf_token %}
{{ forms|crispy }}
<input type="submit" class="" value="Submit">
</form>
{% endblock %}
https://django-crispy-forms.readthedocs.io/en/latest/

Related

Invalid block tag on line 24: 'form.as_p', expected 'endblock'. Did you forget to register or load this tag?

I'm a new in Django and trying to do a app but now I'm having this error: "Invalid block tag on line 24: 'form.as_p', expected 'endblock'."
TEMPLATE
{% extends "base.html" %}
{% block title %}
<title>Tarefas</title>
{% endblock title %}
{% block content %}
<div class="content">
{% if messages %}
<div class="container">
<br>
{% for message in messages %}
<div class="alert alert-info" role="alert">
{{message}}
</div>
{% endfor %}
</div>
{% endif %}
<div class="container tasks-box">
<table class="table table-striped">
<form method='POST'>
{% csrf_token %}
{% form.as_p %}
<button type="submit" class="btn btn-secondary btn-sec">Adicionar</button>
</form>
[...]
forms.py
from django.forms import ModelForm
from todolist.models import Tasks
class TaskForm(ModelForm):
class Meta:
model = Tasks
fields = ['task','responsible']
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from todolist.models import Tasks
from todolist.forms import TaskForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
#login_required
def todolist(request):
if request.method == 'POST':
form = TaskForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.manager = request.user
instance.save()
messages.success(request,("Tarefa adicionada"))
return redirect('todolist')
else:
form = TaskForm
all_tasks = Tasks.objects.filter(manager=request.user)
all_users = Tasks.objects.all()
return render(request,'todolist.html',{ 'form':form,
'all_tasks':all_tasks,
'all_users':all_users})
models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
# Create your models here.
User = get_user_model()
class Tasks(models.Model):
manager = models.ForeignKey(User, on_delete=models.CASCADE,default=None, related_name='tasks_manager')
task = models.CharField(max_length=300)
done = models.BooleanField(default=False)
responsible = models.ForeignKey(User, on_delete=models.CASCADE, default=None, related_name='tasks_responsible', blank=True, null=True)
def __str__(self):
return self.task
I tryed don't use {{ form }} tag in template and thats work.
I think the problem is in views, but i can't figure out why.
Someone can help me?
From form rendering options as documented
All you need to do to get your form into a template is to place the form instance into the template context. So if your form is called form in the context, {{ form }} will render its and elements appropriately.
There are other output options though for the / pairs:
{{ form.as_table }} will render them as table cells wrapped in <tr> tags
{{ form.as_p }} will render them wrapped in <p> tags
{{ form.as_ul }} will render them wrapped in <li> tags
So you have a typo error in {% form.as_p %} just replace this with {{ form.as_p }}

Model form is not able to save in database

I am a beginner in Django
I want to save a form data in database but i am not able to save, followed some tutorials also.
form.py:
from django.forms import ModelForm
from .models import *
class listsForm(ModelForm):
class Meta:
model = todo
fields = "__all__"
views.py:
from django.shortcuts import render
from .models import *
from .form import *
def index(request):
lists = todo.objects.all()
form = listsForm()
context = {
'lists':lists,
'form':form,
}
if request.method == 'POST':
form = listsForm(request.POST)
if form.is_valid:
form.save()
return render(request, 'index.html', context)
models.py:
from django.db import models
class todo(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
created = models.DateField(auto_now_add=True)
def __str__(self):
return self.title
Why are you rendering listsForm?
Your form should be in the template not rendered!
In index.html, your form should looks like the following:
<form action="{% url 'create_todo' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" id="title" required></div>
<div class="form-group">
<label for="Description">Description</label>
<textarea name="description" class="form-control" id="description" ></textarea></div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
In views.py
def index(request):
return render(request, 'index.html')
def create_todo(request):
if request.method == 'POST':
form = listsForm(request.POST)
if form.is_valid():
form.save()
return redirect('index')
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('create_todo/', views.create_todo, name='create_todo')
]
You will still need to render existed todos, preferably in another template.
So in views.py
def alltodos(request):
todos = Todo.objects.all()
return render(request, 'index.html', {'todos':todos})
In index.html, above form or after it, it doesn't matter, just for clear visibility
<div class="row justify-content-center mt-5">
<div class="col-md-10">
{% if todos %}
<div class="list-group">
{% for todo in todos %}
<a class="list-group-item list-group-item-action><b>{{ todo.title }}</b>{{ todo.description|truncatechars:30 }}{% endif %}</a>
{% endfor %}
</div>
{% else %}
<div class="text-center">
<h2>Looks like you don't have any todos!</h2>
<br>
</div>
{% endif %}
</div>
</div>
In urls.py add
path('todos', views.alltodos, name='alltodos'),
Advanced project of mine
I have find out why it was not working,
I was using <input type="button"> for submit button
but when I changed it to <button type="submit"> it works.

How to get a pre-populated form while updating form in django

This is my forms.
class CreateBooksForm(forms.ModelForm):
languages = forms.CharField(widget=forms.TextInput)
file = forms.FileField(widget=forms.FileInput(attrs={'accept':'application/pdf'}))
class Meta:
model = Book
fields = "name","languages", "about","image","file"
This is my view.So when I render to my update view template I get the empty form for languages and files but other are populated.
#login_required
def post_update(request,pk):
update = get_object_or_404(Book,pk=pk)
form = CreateBooksForm(request.POST or None ,request.FILES or None,instance=update)
if request.method == 'POST':
if form.is_valid():
post = form.save(commit=False)
languages = form.cleaned_data['languages']
post.save() # must be save before adding m2m
tag_list=[Language.objects.get_or_create(name=tag)[0] for tag in post.languages.lower().split()]
for tag in tag_list:
a = post.language.add(tag)
post.language.set = a
post.save()
messages.success(request,'Updated successfully!')
update_book.delay(post.pk)
context ={
'form':form
}
return render(request,'books/update.html',context)
my template.So this is simple django crispy template I have used.
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<img class="rounded-circle" src="/media/{{form.image.value}}" height="100px" width="150px">
{{ form|crispy }}
<button type="submit" class="btn btn-dark">Update Books</button>
</form>
You'll have to render each field manually to get the prepopulated field.
for example:
{% for field in form %}
{% if field.languages %}
<input type="name" id={{ field.languages.id_for_label }} value={{ field.languages.value }}/>
{% endif %}
{% endfor %}
for more details refer docs

How to save the list obtained from checkbox in django Modelform in databsae

Here, I am trying to save the multiple items checked from my form into the database using django Modelform. I got the list of item using the query but I couldn't save the data. Everything else works fine, the data from other fields are being saved in the database. How can I save these multiple items I got from checkbox?
models.py
class MyModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
skills = models.ManyToManyField(Skills, blank=True, null=True)
facility = models.ManyToManyField(Facility, blank=True, null=True)
forms.py
class AddMyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = '__all__'
views.py
def my_view(request, slug):
if request.method == 'POST':
form = AddMyModelForm(request.POST or None)
if form.is_valid():
form.save()
form.save_m2m()
return redirect('/')
else:
form = AddMyModelForm()
context = {'form': form}
return render(request, 'template.html', context)
template
<form action="{% url '...' type.slug %}" method="post">
{% csrf_token %}
<h3>Choose the below skills:</h3>
{% for skill in skills %}
<input type="checkbox" name="skills" id="skill-{{ skill.id }}" value="{{ skill.id }}">
<label for="skill-{{ skill.id }}">{{ skill.title }}</label>
{% endfor %}
<h3>Choose the facilities below:</h3>
{% for facility in facilities %}
<input type="checkbox" name="facility" id="facility-{{ facility.id }}"
value="{{ facility.id }}">
<label for="facility-{{ facility.id }}">{{ facility.title }}</label>
{% endfor %}
<button type="submit">Submit</button>
</form>

Python Django How to save choice using model class "CHOICE"?

In my models.py, I have class with LEVEL_CHOICES and Level.
First I builded my project with a textfield Level and it worked. Then I decided to change my Level in order to give users only certain choices. Therefore I edited my models.py and I have now:
class Eleve(models.Model):
FIRST = 'FIRST'
SECOND = 'SECOND'
THIRD = 'THIRD'
LEVEL_CHOICES = (
('FIRST', 'School'),
('SECOND', 'HighSchool'),
('THIRD', 'University'),
)
Level = models.CharField(max_length=3, choices=LEVEL_CHOICES, default='FIRST')
I think that there is a problem in my views.py because I'am able to save class Eleve through Admin app. I'm also using a decorator in order to have REcaptchaV2.
def Form(request):
form = ResgisterStud(request.POST)
if request.recaptcha_is_valid and form.is_valid():
form.save(commit=False)
form.save()
return render(request, 'form.html', {'form': form})
else:
return render(request, 'form.html', {'form': form})
my forms.py
class ResgisterStud(forms.ModelForm):
class Meta:
model = Eleve
My Form.html
<form action="{% url "form" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="col-md-6 form-group">
{{ form.Level|add_class:"form-control" }}
</div>
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="form-group g-recaptcha" data-sitekey="***"></div>
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endfor %}
{% endif %}
</form>

Categories