Why is my Django form is not displaying anything? - python

I am following a tutorial in which we will create a form to hold simple object parameters.
Here's the code:
forms.py
from django.forms import ModelForm
from .models import Item
class ItemForm(ModelForm):
class Meta:
model = Item
fields = ['item_name', 'item_desc', 'item_price', 'item_image']
models.py
from django.db import models
class Item(models.Model):
def __str__(self):
return self.item_name
item_name = models.CharField(max_length = 200)
item_desc = models.CharField(max_length= 200)
item_price = models.IntegerField()
item_image = models.CharField(max_length=500, default ="https://i.jamesvillas.co.uk/images/jvh/holiday-destinations/resort/food-placeholder.jpg" )
urls.py
from . import views
from django.urls import path
urlpatterns = [
path('', views.index, name = 'index'),
path('item/', views.item, name = 'item'),
path('info/', views.info, name = "info"),
path('<int:item_id>/', views.detail, name = "detail" ),
#add form
path('add', views.create_item, name = "create"),
]
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Item
from django.template import loader
from .forms import ItemForm
#Some code here
def create_item(request):
form = ItemForm(request.POST or None)
if (form.is_valid()):
form.save()
return redirect('food/index')
return render(request, 'food/item-form.html', {'form': form})
food/item-form.html
<form method = "POST">
{% csrf_token %}
{{ form }}
<button type= "Submit" >Save</button>
</form>
Now when I go to http://localhost:8000/food/add, it displays an empty page! I have followed the tutorial the exact same way then why is My project not working?

correct your views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
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('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})

Related

Django Can't See Where I Typed in User ID

So I'm creating a web app in Django, and I encountered this error:
my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<int:user_id>/', views.profile, name="profile"),
#path('signup/', views.signup, name="signup"),
path("signup/", views.signup, name="signup")
]
my views.py:
from django.shortcuts import render, get_object_or_404
from django.contrib.auth import forms
from django.urls import reverse_lazy
from django.http import HttpResponse, Http404
from django.template import loader
from .models import User
from .forms import SignUpForm
from datetime import datetime
def index(request):
cool_people_list = User.objects.order_by("-username")[:5]
_template = loader.get_template("front_page.html")
context = {
"cool_people_list" : cool_people_list,
}
return HttpResponse(_template.render(context, request))
def profile(request, user_id):
try:
user = get_object_or_404(User, pk=user_id)
_template = loader.get_template("profile.html")
context = {
"user" : user
}
return HttpResponse(_template.render(context, request))
except:
raise Http404("The user you are looking for doesn't exist.")
def signup(request):
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
rn = str(datetime.today().strftime("%Y-%m-%D"))
rn2 = str(datetime.today)
"""usr_list = User.objects.order_by('-join_date')
latest_usr = usr_list.first()"""
new_user = User(3, str(form.cleaned_data.get("username")), str(form.cleaned_data.get("password")), rn, rn2)
new_user.save()
return render(request, "signup.html")
my models.py:
from django.db import models
from django.core.validators import MinLengthValidator
import datetime
class User(models.Model):
user_id = models.IntegerField(unique=True)
username = models.CharField(max_length=25, validators=[MinLengthValidator(3)])
password = models.CharField(max_length=25, validators=[MinLengthValidator(7)])
join_date = models.DateField()
last_online = models.DateTimeField()
def __str__(self):
return self.username
I kept trying different methods, like manually adding the user ID (temporary fix), but Django can't see where I type in the ID! It doesn't register it when I typed it in what I believe is the correct format for my 'User' model.
You need to save an object in User Model like this...
def signup(request):
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
rn = datetime.today().strftime("%Y-%m-%D")
rn2 = datetime.today
new_user = User(username= form.cleaned_data["username"], password=form.cleaned_data["password"], rn=rn, rn2=rn2)
new_user.save()
else:
form.errors
return render(request, "signup.html")

I am not able to understand this error: TypeError: cannot convert dictionary update sequence element #0 to a sequence

I am getting stuck with the new_entry functionality , This is a project in the crash course for python book , I have tried to verify my code a number of times not able to figure out why I get this error:
TypeError: cannot convert dictionary update sequence element #0 to a sequence
File views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .models import Topic
from .forms import TopicForm
from .forms import EntryForm
def index(request):
return render(request, 'learning_logs/index.html')
def topics(request):
# display all the topics
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
def topic(request, topic_id):
# display entries pertaining to a topic
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
def new_topic(request):
# fill a new topic
if request.method != 'POST':
# No data submitted , create a blank form
form = TopicForm()
else:
# post data submitted , process data
form = TopicForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)
def new_entry(request, topic_id):
# Enter a new entry into any topic
topic = Topic.objects.get(id=topic_id)
if request.method != 'POST':
# NO data submitted , create a blank form
form = EntryForm()
else:
# post data submitted , process data
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic_id]))
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
File urls.py
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [ # Homepage
path('', views.index, name='index'),
# topics
path('topics', views.topics, name='topics'),
# entries about each topic
path('<topic_id>/topic/', views.topic, name='topic'),
# page for adding a new topic
path('new_topic/', views.new_topic, name='new_topic'),
# adding entries
path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry'),
]
And this is the place where i am getting stuck with the new_entry functionality, file new_entry.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>{{ topic }}</p>
<p>New entry</p>
<form action="{% url 'learning_logs:new_entry' topic.id %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button name="submit">add entry</button>
</form>
{% endblock content %}
File forms.py
from django import forms
from .models import Topic
from .models import Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols', 80})}
File models.py
from django.db import models
class Topic(models.Model):
# A topic that the user is learning about
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
# Return the info as a string
return self.text
class Entry(models.Model):
# something specific learned about a topic
topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "entries"
def __str__(self):
# A representation of the data in string form
if len(self.text) > 50:
return str(self.text)[:50] + "...."``
else:
return self.text
I suspect the error is in your EntryForm.Meta.widgets; attrs is supposed to be a dict (should be written as {'cols': 80}), but you are passing a set with 2 elements (you wrote {'cols', 80}).
Notice how you used a comma , instead of a colon :.
The corrected code would be:
class EntryForm(forms.ModelForm):
class Meta:
...
widgets = {
'text': forms.Textarea(attrs={'cols': 80}),
}

How to make delete button in Django

Help me please to understand how to make the delete button, its must to delete a Cat
class Cat(models.Model):
class Meta():
db_table = "cat"
paw = models.IntegerField(default=4)
name = models.CharField(max_length=30, null=False, default='Cat')
age = models.IntegerField(default=False, null=False)
species = models.CharField(max_length=50, blank=True)
hairiness = models.IntegerField(default=False, null=False)
def __str__(self):
return self.name
This is my views.py, hope you can help. (it's need for my job interview on Monday)
from django.shortcuts import render, get_object_or_404
from .models import Cat
from .forms import CatForm
from django.shortcuts import redirect
def home(request):
template = "base.html"
queryset = Cat.objects.all()
context = {
"object_list": queryset
}
return render(request, template, context)
def new_cat(request):
if request.method == "POST":
form = CatForm(request.POST)
if form.is_valid():
cat = form.save(commit=False)
cat.save()
return redirect('/', pk=cat.pk)
else:
form = CatForm()
return render(request, 'new_cat.html', {'form': form})
def cat_edit(request, pk):
cat = get_object_or_404(Cat, pk=pk)
if request.method == "POST":
form = CatForm(request.POST, instance=cat)
if form.is_valid():
cat = form.save(commit=False)
cat.save()
return redirect('/', pk=cat.pk)
else:
form = CatForm(instance=cat)
return render(request, 'new_cat.html', {'form': form})
site is asc to addd more details, but i just don't know what else, i can add.
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^new/$', views.new_cat, name='new_cat'),
url(r'^edit/(?P<pk>[0-9]+)/$', views.cat_edit, name='cat_edit'),
]
At first, you should create a cat_delete view, which should look something like this:
def cat_delete(request, pk):
cat = get_object_or_404(Cat, pk=pk) # Get your current cat
if request.method == 'POST': # If method is POST,
cat.delete() # delete the cat.
return redirect('/') # Finally, redirect to the homepage.
return render(request, 'template_name.html', {'cat': cat})
# If method is not POST, render the default template.
# *Note*: Replace 'template_name.html' with your corresponding template name.
Then, you should map this view in your urls.py:
from django.conf.urls import url
from . import views
app_name = 'cats'
# Note that app_name is added here!
# It is used as a namespace in order to reverse your urls better.
# See usage in template.
urlpatterns = [
# ...
url(r'^delete/(?P<pk>[0-9]+)/$', views.cat_delete, name='cat_delete')
]
In your template, you should create a form with delete button, which will simply send a POST request to the delete view:
<form action="{% url 'cats:cat_delete' cat.id %}" method="post">
{% csrf_token %}
<input type="submit" value="Delete cat">
</form>
Look closely on the form's action:
{% url 'cats:cat_delete' cat.id %}
Here I am using the app_name from urls.py that I previously added in order to resolve your urls by name, not by path. Now cats:cat_delete will evaluate to cats/delete/<pk>. And of course you pass the cat.id.
This should do the trick with deleting instance of your Cat model. Hope I helped.

Django views.py request and query

I have a contact page for my website. The contact form is working but I want to add a background image to this page (which is saved in the database).But how can I combine my email(request) and a query to get the image ?
views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import ContactForm
def email(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, from_email, ['admin#example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('./success')
return render(request, "contact/email.html", {'form': form})
def success(request):
return HttpResponse('Success! Thank you for your message.')
models.py
from django.db import models
class Background(models.Model):
name = models.CharField(max_length=200, null=False)
image = models.ImageField(upload_to='./background/', default=None)
def __str__(self):
return self.name
urls.py
from django.conf.urls import url
from . import views
app_name = 'contact'
urlpatterns = [
url(r'^$', views.email, name='email'),
url(r'^success/$', views.success, name='success'),
]
You could retrieve the image on your view:
def get_background():
try:
background = Background.objects.get(name="your image name") # add your filters where to get the image
if background.image and background.image.url:
return background.image.url
except Background.DoesNotExist:
return
def email(request):
if request.method == 'GET':
form = ContactForm()
else:
...
...
# add the background to context
return render(request, "contact/email.html", {'form': form, 'background_img': get_background()})
And in your HTML (it's just a exemple, always try to style your site with a separate css file):
...
<div {% if background_img %}style="background: url('{{background_img}}') center no-repeat;"{% endif %}>
...

How to work with Mezzanine

processor_for.py
from django import forms
from django.http import HttpResponseRedirect
from mezzanine.pages.page_processors import processor_for
from .models import Book
class BookForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
#processor_for(Author)
def author_form(request, page):
form = BookForm()
if request.method == "POST":
form =BookForm(request.POST)
if form.is_valid():
# Form processing goes here.
redirect = request.path + "?submitted=true"
return HttpResponseRedirect(redirect)
return {"form": form}
models.py
from django.db import models
from time import time
class Book(models.Model):
book_name= models.CharField(max_length=200, unique = True)
def __unicode__(self):
return self.book_name
views.py
def create_book (request):
if request.POST:
form = BookForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/all/')
else:
form = BookForm()
args= {}
args.update(csrf(request))
args['form'] = form
return render_to_response('create_Book.html', args)
urls.py
urlpatterns += patterns('',
url(r'^/xyz/$', create_book))
create_Book.html
<form action="/xyz/" method="post" enctype="multipart/form-data">{% csrf_token %}
{{form.as_ul}}
<input type="submit" name="submit" value="create"/>
</form>
This is what i am doing but still i am unable to access form. Where i am doing wrong. will be grateful to you. Please mark that what's wrong in code?
as per you code and your explanation in question .please see your code in urls.py
urlpatterns += patterns('',
url(r'^xyz/$', create_book)) # you should write like ^xyz/$
Please follow django doc
Two Syntax Problems:
1) Always define your processor name in " " like #processor_for("Author")
2) urls for page processors like :
url("^xyz/$", "mezzanine.pages.views.page", {"slug": "Author"}, name="Author"),

Categories