Can't get forms to render in Django - python

I'm working on a project and I don't get the django forms to render on any of my pages. I've compared it to django girls code, as that is what I usually consult but it looks virtually identical to it. It's not just this page, my other pages have issues with rendering the forms as well. Here's the code:
Views.py
from django.shortcuts import render
from .models import *
from .forms import *
from django.shortcuts import render, get_object_or_404
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.db.models import Sum
from django.utils import timezone
from django.views.decorators.http import require_POST
from .cart import Cart
from django.db import transaction
from django.contrib import messages
#login_required
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=Post)
return render(request, 'rentadevapp/post_edit.html', {'rentadevapp': post_edit}, {'form': form})
Forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
post_edit.html
{% extends 'rentadevapp/base.html' %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block content %}
<head>
<link rel="stylesheet" href="{% static 'css/post_edit.css' %}">
</head>
<body>
<div class="container"><br>
<h2>New Post</h2><br>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
</div>
</body>
{% endblock %}
Models.py
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
updated_date = models.DateTimeField(auto_now_add=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default='0')
class Meta:
ordering = ('title',)
def created(self):
self.created_date = timezone.now()
self.save()
def updated(self):
self.updated_date = timezone.now()
self.save()
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
I'm pretty stuck and have spent a couple hours trying to figure this out. Any help is really appreciated.
Thanks!

Your form isn't returned to the template in the context.
In Django 1.11 or 2.2 the render function call in your view should return a dictionary of context variables as the third argument, but you've got two dictionaries. The 4th argument where you've got a dictionary containing the form is being passed as content_type which is then used in the HttpResponse so I'm quite surprised there isn't something strange happening or an error seen.
So you're doing;
return render(request, 'rentadevapp/post_edit.html', {'rentadevapp': post_edit}, {'form': form})
What you need to do is;
context = {'form': form, 'rentadevapp': post_edit}
return render(request, 'rentadevapp/post_edit.html', context)
Prior to 1.10 render had a different signature, but the first three arguments of request, template_name, context have been that way since <1.8

Related

My form data is not being displayed on html template

i made a form and now i am trying to to view the data from the form on the html template but its not working, any help would be helpful i just want the the data entered through the the form to be displayed on the html page. Here is the code
views.py
from django.shortcuts import render
from .models import Post
from.forms import TaskForm
def add_task(request):
form = TaskForm()
if request.method == 'POST':
print(request.POST)
form = TaskForm(request.POST)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'List/add_task.html', context)
def home(request):
return render(request, 'List/home.html')
def task_list(request):
context = {
'posts': Post.objects.all(),
}
return render(request, 'List/task.html', context)
models.py
from django.db import models
class Post(models.Model):
Task = models.CharField(max_length=50, default='pythons')
Detail = models.TextField(max_length=100, default='python')
date = models.DateTimeField(auto_now_add=True)
forms.py
from django.forms import ModelForm
from .views import Post
class TaskForm(ModelForm):
class Meta:
model = Post
fields = '__all__'
task.html
{% extends "List/Home.html" %}
{% block content %}
{% for post in posts %}
<h3>{{ post.title }}</h3>
<h3>{{ post.detail }}</h3>
{% endfor %}
{% endblock content %}
in your Post model you have fields name Task and Detail and in your template you are looking for field title and detail

"Post.user" must be a "User" instance

I am new to using django and I'm creating a simple webpage that takes in user input and saves it to the Model Form
models.py:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
post = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
forms.py
from django import forms
from .models import Post
class HomeForm(forms.ModelForm):
post = forms.CharField()
class Meta:
model = Post
fields = ('post',)
views.py
from django.shortcuts import render, redirect
# Create your views here.
from django.http import HttpResponse
from django.views.generic import TemplateView
from .forms import HomeForm
class HomeView(TemplateView):
template_name = 'home.html'
def get(self, request):
form = HomeForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = HomeForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
text = form.cleaned_data['post']
form = HomeForm()
return redirect('home.html')
args = {'form': form, 'text': text}
return render(request, self.template_name, args)
home.html
{% block body %}
<div class ='container'>
<h1>Home</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type ='submit'>Submit</button>
</form>
</div>
{% endblock %}
When I run the server the webpage comes up normal but when I type in some input an error page pops up and says : ValueError at /
Cannot assign ">": "Post.user" must be a "User" instance.
Any Help would be appreciated!

Django form fields not loading in template

I can't seem to get a model form to load in my template.
models.py
from django.db import models
class Event(models.Model):
name = models.CharField(max_length=60)
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField()
description = models.TextField()
forms.py
from django import forms
from .models import Event
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['name']
views.py
from django.shortcuts import render
from .forms import EventForm
def index(request):
if request.method == 'POST':
form = EventForm(request.POST)
if form.is_valid():
form.save()
else:
form = EventForm()
return render(request, 'index.html')
index.html
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
</form>
<button type="submit">Save</button>
I can get the form to print to the console on load when adding print(form) in views.py on the GET request, but it doesn't load in the template.
Good examples on different ways to use forms : https://docs.djangoproject.com/en/1.11/topics/forms/#the-view
For index.html to render it is expecting form variable. So Render method call should be like this:
render(request, 'index.html', {'form': form})

Input in forms not getting through in Django

I'm following Mike Hibbert's tutorial on links. The site works perfectly fine, however, the input I put in the form is not being updated or transmitted in the database.
from forms import LocationForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.http import HttpResponse
from core.models import Location
from django.shortcuts import render
class LocationListView(ListView):
model = coremodels.Location
template_name='location/list.html'
def create2(request):
if request.method =='POST':
form = LocationForm(request.POST)
if form.is_valid():
form.save
return HttpResponseRedirect('/location/')
else:
form = LocationForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('location/create_location.html', args)
my models.py
class Location(models.Model):
title = models.CharField(max_length=300)
description = models.TextField(null=True, blank=True)
address = models.TextField(null=True, blank=True)
hours = models.TextField(null=True, blank=True)
my create_location.html:
{% block sidebar %}
<ul>
<li> Cancel</li>
</ul>
{% endblock %}
<form action="" method="post"> {% csrf_token %}
<ul>
{{form.as_ul}}
</ul>
and finally my forms.py
from django import forms
from models import Location
class LocationForm (forms.ModelForm):
class Meta:
model = Location
fields =('title', 'description', 'address')
<input type="submit" name="submit" value="create location">
</form>
No error or anything, site works perfect, however if I click on create new location and try submit a new location on the create_location.html it goes back to the locations (list.html) but without the new one.
I also tried updating the views with the code from the documentation
return render(request, 'location/create_location.html',{'form': form})
but didn't work.
What do I do wrong?
Thanks in advance
def create2(request):
if request.method =='POST':
form = LocationForm(request.POST)
if form.is_valid():
form.save
You're not calling form.save(), you're just "stating" the function name (which here does nothing).
Use
def create2(request):
if request.method =='POST':
form = LocationForm(request.POST)
if form.is_valid():
form.save()
and you should be good to go.

Django save() is not saving form to database

Hello I have problem with saving forms to database. When I try to save the AdHistoryForm in ads_history_add view the forim is rendered correctly but after submitting nothing happens aside of redirecting me to ads_history_list view.
In addition when I try to submit this form with empty field it doesnt show any errors (I included them in template), so maybe it is validation thing.
When I try to add Ad in ads_add view everything is ok.
Can you help me?
models.py
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
class Ad(models.Model):
title = models.CharField(max_length=128, verbose_name=_("name"), help_text=_("required"), unique=True)
content = models.TextField(verbose_name=_("content"), blank=True)
url = models.URLField(verbose_name=_("website"), blank=True)
date_create = models.DateTimeField(auto_now_add=True)
date_modify = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.title
class AdHistory(models.Model):
ad = models.ForeignKey(Ad)
user = models.ForeignKey(User)
comment = models.TextField(verbose_name=_("comment"), help_text=_("required"))
date_create = models.DateTimeField(auto_now_add=True)
date_modify = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.comment
forms.py
from django import forms
from .models import Ad, AdHistory
class AdForm(forms.ModelForm):
class Meta:
model = Ad
fields = ['title', 'content', 'url']
class AdHistoryForm(forms.ModelForm):
class Meta:
model = AdHistory
fields = ['comment']
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
from django.utils.translation import ugettext as _
from .models import Ad, AdHistory
from .forms import AdForm, AdHistoryForm
#login_required
#user_passes_test(lambda u: u.is_superuser)
def ads_list(request):
ads_list = Ad.objects.all().order_by('-date_modify')
context = {'list': ads_list}
return render(request, 'ads_list.html', context)
#login_required
#user_passes_test(lambda u: u.is_superuser)
def ads_add(request):
form = AdForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('ads_list')
context = {'form': form}
return render(request, 'ads_form_add.html', context)
#login_required
#user_passes_test(lambda u: u.is_superuser)
def ads_history_list(request, ad_id):
ad = get_object_or_404(Ad, pk=ad_id)
history_list = AdHistory.objects.select_related().filter(ad=ad).order_by('-id')
context = {'list': history_list, 'object': ad}
return render(request, 'ads_history_list.html', context)
#login_required
#user_passes_test(lambda u: u.is_superuser)
def ads_history_add(request, ad_id):
ad = get_object_or_404(Ad, pk=ad_id)
f = AdHistoryForm(request.POST or None)
if f.is_valid():
new_entry = f.save(commit=False)
new_entry.ad = ad
new_entry.user = request.user
new_entry.save()
return redirect('ads_history_list', ad_id)
context = {'form': f, 'object': ad}
return render(request, 'ads_history_add.html', context)
urls.py
rom django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from ads import views
urlpatterns = patterns(
'',
url(r'^$', views.ads_list, name="ads_list"),
url(r'^add/', views.ads_add, name="ads_add"),
url(r'^(?P<ad_id>\d+)/history/$', views.ads_history_list, name="ads_history_list"),
url(r'^(?P<ad_id>\d+)/history/add$', views.ads_history_add, name="ads_history_add"),
)
both form templates inherits from this template:
<form role="form" method="post" action=".">
{% csrf_token %}
<table class="table table-bordered crm-form">
{% for field in form.visible_fields %}
<tr>
<th>
{{ field.label }}
</th>
<td>
{{ field }}
<small>{{ field.help_text }}</small>
{% if field.errors %}
<div class="alert alert-danger" role="alert">{{ field.errors }}</div>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<button type="submit" name="submit" class="btn btn-success crm-float-right">
{% trans 'Save' %}
</button>
</form>
The POST request never reaches your ads_history_add view because your ads_history_add URL pattern does not have a trailing slash. Without the trailing slash, action="." in the ads_form_add.html template results in a POST to (?P<ad_id>\d+)/history/
Add the trailing slash and everything should work as expected. Alternatively, you could omit the action attribute to tell the browser to POST to the current URL.
Also note that, although not relevant here, it is probably a good habit to display {{ form.non_field_errors }}.

Categories