Django basic ModelForm not showing choices - python

Using Django tutorial, I built a basic ModelForm with choice fields:
One field (Shirt size) - is not showing choices
Second field - not showing at all
I can't find the reason, anywhere I checked it seems like I'm doing things right, but obviously I'm not.
Thank you.
The Result Form
views.py
def person(request):
if request.method == 'POST':
form = forms.PersonForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = forms.PersonForm()
return render(request, 'development/form_template.html', {'form': form})
forms.py
class PersonForm(ModelForm):
class Meta:
model = models.Person
fields = '__all__'
models.py
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60, default='Anonymous', help_text='Type your name.')
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
medal_type = models.TextChoices('MedalType', 'GOLD SILVER BRONZE')
form_template.html
{% extends 'development/development_template.html' %}
{% block content %}
<div class="container">
<form action="/your-name/" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
</div>
{% endblock content %}
CSS files I'm using
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link type="text/css" rel="stylesheet" href="{% static 'css/style.css' %}">

The problem was 100% the support of Materializecss design in select - for some reason it's not supporting select anymore.
I used bootstrap4 to execute the form pages:
(1) install: pip install django-bootstrap4
(2) add to INSTALLED_APPS = [..., 'bootstrap4',]
(3) edit your HTML form
Here's html for example:
{% extends 'adolim/adolim_template.html' %}
{% block content %}
{% load bootstrap4 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
<div class="container" style="width:100%;" dir="rtl">
<div class="col s3 right">
</div>
<div class="col s6 right" dir="rtl">
<div class="container">
<div class="row"><br></div>
<h4 class="right">{{ page_title }}</h4>
<div class="row"><br></div>
<form dir="rtl" action="{% url 'adolim:add_order' %}" method="post" >
{% csrf_token %}
{% bootstrap_form form %}
<div class="col center">
{% buttons %}
<button class="btn-large waves-effect waves-light blue darken-1" type="submit" name="action">{{ page_title }} למערכת
<i class="material-icons right">send</i>
</button>
{% endbuttons %}
</div>
</form>
</div>
</div>
</div>
{% endblock content %}

Related

Why is my create button not redirecting to the form? (For django)

I am new to Django and am trying to make an online journal, and the server runs fine, but when I press the create button, it does not redirect to the form even though a POST request is being sent. screenshot of the create page. I'm not sure why.
This is the code:
views.py:
from django.shortcuts import render, redirect, get_object_or_404
from ejournal.models import Journal
from ejournal.forms import JournalForm
def make_entry(request):
if request.method == "POST":
entry = JournalForm(request.POST, request.FILES)
if entry.is_valid():
entry.save()
return redirect('list_journals')
else:
entry = JournalForm()
context = {
'entry':entry
}
return render(request, 'ejournal/create.html', context)
def delete_entry(request, id):
entry = get_object_or_404(Journal, id=id)
if request.method == "POST":
entry.delete()
return redirect('list_journals')
context = {
'object':object
}
return render(request, 'journal/delete.html',context)
def list_journals(request):
entries = Journal.objects.all()
context = {
'entries': entries
}
return render(request, 'ejournal/list_journals.html',context)
def journal_detail(request, id):
journal = Journal.objects.get(id=id)
context = {
'journal':journal
}
return render(request, 'journal/journal_detail.html', context)
forms.py
from ejournal.models import Journal
from django.forms import ModelForm
class JournalForm(ModelForm):
class Meta:
model = Journal
fields = ['name','title','text','image']
models.py
from django.db import models
class Journal(models.Model):
name = models.CharField(max_length=20)
title = models.CharField(max_length=50)
text = models.TextField(max_length=1000)
date = models.DateField(auto_now_add=True)
image = models.FileField(upload_to='')
archived = models.BooleanField(default=False)
def __str__(self):
return self.name
base.html
{% load static %}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>My Online Journal</title>
<!-- Bootstrap core CSS -->
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static 'css/style.css' %}" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{% url 'list_journals' %}">Smart Journal</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="btn btn-outline-info btn-md" href="{% url 'list_journals' %}">LIST ALL</a>
</li>
</ul>
</div>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="btn btn-outline-info btn-md" href="{% url 'make_entry' %}">+ New Journal Entry </a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Page Content -->
<div class="container" id="app">
{% block content %}
{% endblock %}
</div>
<!-- /.container -->
<!-- Bootstrap core JavaScript -->
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>
create.html
{% extends 'ejournal/base.html' %}
{% block content %}
<div class="center_journal">
<h1> Create Journal Entry </h1>
</div>
<div class="center_journal">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<button class="btn btn-primary" type="submit">CREATE</button>
</form>
</div>
{% endblock content %}
urls.py
from django.urls import path
from ejournal.views import make_entry, delete_entry, list_journals, journal_detail
urlpatterns = [
path('create', make_entry, name="make_entry"),
path('list_journals', list_journals, name="list_journals"),
path('delete/<int:id>/', delete_entry, name="delete_entry"),
path('journal_detail/<int:id>',journal_detail, name="journal_detail"),
]
You pass the form as the variable entry to your template ejournal/create.html.
Inside this template you use {{ form.as_p }}, but form is undefined. You need to use the variable entry because thats where the form is assigned to.
So your create.html becomes this:
{% extends 'ejournal/base.html' %}
{% block content %}
<div class="center_journal">
<h1> Create Journal Entry </h1>
</div>
<div class="center_journal">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ entry.as_p }}</p>
<button class="btn btn-primary" type="submit">CREATE</button>
</form>
</div>
{% endblock content %}
You're checking if your form is valid by using entry.is_valid(), but your form will always be invalid because you didn't pass the correct form in your template, as described above.
Check with form's action='' attribute like this...
<form method="POST" action="{% url 'make_entry' %}" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<button class="btn btn-primary" type="submit">CREATE</button>
</form>

Passing template variable to parent in Django

I have a number of apps that each have their own intro section. This intro section has quite a few lines of HTML and only a few lines are adjusted for each app (Think title and intro). I would like this intro section to live at the project level (where the navbar template lives), but I can't find a way to pass template variables from the app to the project.
All of my apps(about 15) follow this template scheme:
app_base.html extends project base.html
app_base.html has an {% include %} to pull in app_intro.html
all <app_unique_templates>.html that are called by <app>/views.py, extend the app_base.html
To reiterate, how can I pass a template variable from /views.py to project base.html template using my app template scheme? If I can't use this scheme, can I adjust it in a way that will allow me to accomplish this?
Thank you all in advance!
views.py:
def add_app_context(view_context):
app_context = {
'app_name': 'Material Database',
'app_desc': 'Long String goes Here For Application Description',
'doc_link': '#',
}
view_context.update(app_context)
return view_context
class MaterialList(ListView):
model = Material
context_object_name = 'materials'
def get_context_data(self):
context = super().get_context_data()
context['pagetitle'] = 'Material List'
context['intro_btn_link'] = '/materials/new'
context['intro_btn_name'] = 'Create New Material'
return add_app_context(context)
app_base.html:
{% extends "mjd_tools/base.html" %}
{% load staticfiles %}
{% block body %}
<link rel="stylesheet" href="{% static 'mat_db/css/style.css' %}">
{% include "mat_db/app_intro.html" %}
{% block list %}{% endblock list %}
{% block form %}{% endblock form %}
<script src="{% static 'mat_db/js/scripts.js' %}"></script>
{% endblock body %}
app_intro.html(this is what I have to repeat for each app).
<div class="row">
<div class="col-sm-8">
<h1>{{ app_name }}</h1>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-8">
<p>
{{ app_desc }}
</p>
</div>
<div class="col-auto ml-auto">
<a class="btn btn-warning" role="button" href="{{ doc_link }}">Documentation</a>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm text-center">
<h4>
<span>{{ pagetitle }}</span>
{% if intro_btn_name %}
<a class="btn btn-primary btn-sm pull-right" role="button"
href="{{ intro_btn_link }}">{{ intro_btn_name }}</a>
</h4>
{% endif %}
</div>
</div>
<hr>

django.urls.exceptions.NoReverseMatch: Reverse for 'favorite' not found

Django version 2.0
views.py
from django.views import generic
from .models import Album
class IndexView(generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
return Album.objects.all()
class DetailView(generic.DetailView):
model = Album
template_name = 'music/details.html'
details.html
{% extends 'music/base.html' %}
{% block body %}
<!-- {{album}} -->
<img src="{{album.album_logo}}">
<h1>{{album.album_title}}</h1>
<h3>{{album.artist}}</h3>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form action="{% url 'music:favorite' album.id %}" method="post">
{% csrf_token %}
{% for song in album.song_set.all %}
<input type="radio" id="song{{ forloop.counter }}" name="song" value="{{ song.id }}">
<label for="song{{ forloop.counter }}">
{{ song.song_title }}
{% if song.is_favorite %}
<img src="http://i.imgur.com/b9b13Rd.png" />
{% endif %}
</label><br>
{% endfor %}
<input type="submit" value="Favorite">
</form>
{% endblock %}
index.html
{% extends 'music/base.html' %}
{% block body %}
{% if all_albums %}
<h3>Here are all my Albums:</h3>
<ul>
{% for album in all_albums %}
<li>{{ album.album_title }}</li>
{% endfor %}
</ul>
{% else %}
<h3>You don't have any albums</h3>
{% endif %}
{% endblock %}
base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Viberr</title>
{% load staticfiles %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link href='https://fonts.googleapis.com/css?family=Satisfy' rel='stylesheet' type="text/css">
<link rel="stylesheet" type="text/css" href="{% static 'music/style.css' %}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Header -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#topNavBar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'music:index' %}">University of Calicut</a>
</div>
<!-- Items -->
<div class="collaps navbar-collaps" id="topNavBar">
<ul class="nav navbar-nav">
<li class="active">
<a href="{% url 'music:index' %}">
<span class="glyphicon glyphicon-cd" aria-hidden="true"></span>
Albums
</a>
</li>
<li class="">
<a href="{% url 'music:index' %}">
<span class="glyphicon glyphicon-music" aria-hidden="true"></span>
Songs
</a>
</li>
</ul>
<form class="navbar-form navbar-left" role="search" method="GET" action="#">
<div>
<input type="text" class="form-control" name="q" value="">
<button type="submit" class="btn btn-default">Search</button>
</div>
</form>
<ul class="nav navbar-nav navbar-right">
<li class="">
<a href="#">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add Album
</a>
</li>
<li class="">
<a href="#">
<span class="glyphicon glyphicon-off" aria-hidden="true"></span>
Logout
</a>
</li>
</ul>
</div>
</div>
</nav>
{% block body %}
{% endblock %}
</body>
</html>
urls.py (music)
from django.conf.urls import url
from .import views
from django.urls import path
app_name = 'music'
urlpatterns = [
url(r'^$',views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='details'),
]
models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=250)
album_title=models.CharField(max_length=500)
genre=models.CharField(max_length=100)
album_logo=models.CharField(max_length=1000)
def __str__(self):
return self.album_title + ' - ' + self.artist
class Song(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(max_length=10)
song_title = models.CharField(max_length=250)
is_favorite = models.BooleanField(default=False)
def __str__(self):
return self.song_title
I attached images of my home page and linked page,
please help me regarding the issue
n the above code, the second page is throwing me a error
django.urls.exceptions.NoReverseMatch: Reverse for 'favorite' not found. 'favorite' is not a valid view function or pattern name**
Please someone help me out where im wrong! Thanks in advance!
I can't see any url with the name favorite here, which is what the error is telling you as well:
app_name = 'music'
urlpatterns = [
url(r'^$',views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='details'),
]
you probably copy pasted the details.html or you simly forgot to specify the "favorite" url in the app "music"
EDIT:
As you have clarified that you are unable to solve the problem on your onw:
Change details.html as such:
<form action="{% url 'music:favorite' album.id %}" method="post">
replace it with
<form action="#" method="post">
you're site should then at least load.
EDIT2:
After watchich the youtube video you linked in your comment:
all the answers are in the video and its comments!
You didn't update details.html. Watch closely around min 1:50.
Btw my solution of replacing the form action will work as well, but the output will be slightly different from what you might expect...
I hope this will get you started ;)

samuelcolvin's django-bootstrap3-datetimepicker not showing calendar when clicked on input field

I am trying to use samuelcolvin's django-bootstrap3-datetimepicker in which its based on Eonasdan's bootstrap-datetimepicker but forked from nkunihiko's django-bootstrap3-datetimepicker to show the calendar so the user can select the date and time and submit it. The issue I am having is that when I try to click on the field or on the right button with the calendar icon in it like in the demo website, it does not show me nothing.
I also had to add widgets.py from the repo into my project since it was giving me a No module named bootstrap3_datetime.widgets error.
Would appreciate your help
This is what I have in my models.py:
class Production(TimeStampedModel):
#Some other code.....
scheduled_date = models.DateTimeField(null=True, blank=True)
fully_produced_date = models.DateTimeField(null=True, blank=True)
forms_schedule.py:
from producer.widgets import DateTimePicker
from django import forms
from .models import Production
class ScheduleForm(forms.ModelForm):
class Meta:
model = Production
fields = ['scheduled_date', 'fully_produced_date']
scheduled_date = forms.DateTimeField(required=False, widget=DateTimePicker(options={"format": "YYYY-MM-DD HH:mm", "pickSeconds": False}))
# def clean_scheduled_date(self):
# scheduled_date = self.cleaned_data.get('scheduled_date')
# return scheduled_date
def clean_fully_produced_date(self):
fully_produced_date = self.cleaned_data.get('fully_produced_date')
return fully_produced_date
views.py
def episodeschedule(request):
title = 'Podcast'
title_align_center = True
subtitle = 'Setup | Add Episode'
subtitle_align_center = True
form = ScheduleForm(request.POST or None)
context = {
"title": title,
"subtitle": subtitle,
"form": form
}
if form.is_valid():
instance = form.save(commit=False)
scheduled_date = form.cleaned_data.get("scheduled_date")
fully_produced_date = form.cleaned_data.get("fully_produced_date")
instance.scheduled_date = scheduled_date
instance.fully_produced_date = fully_produced_date
instance.user = request.user
instance.save()
return render(request, "forms_schedule.html", context)
else:
return render(request, "forms_schedule.html", context)
And forms_schedule.html:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-success active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
<span class="sr-only">100% Complete</span>
</div>
</div>
<div class="panel panel-default box-shadow--16dp col-sm-6 col-sm-offset-3">
<div class="panel-body">
<div class='row'>
<div class='col-sm-12'>
{% if title %}
<h1 class='{% if title_align_center %}text-align-center{% endif %}'>{{ title }}<!-- : {{ get.clientsetup.company_name }} --></h1>
{% endif %}
{% if subtitle %}
<h3 class='{% if subtitle_align_center %}text-align-center{% endif %}'>{{ subtitle }}</h4>
{% endif %}
<h5>Schedule</h5>
<form method='POST' action=''>{% csrf_token %}
{{ form|crispy }}
<hr/>
<input class='btn btn-info box-shadow--6dp' type='submit' value='Save' />
<p>
<p>
<a class="btn btn-primary box-shadow--6dp" href="{% url 'dashboard' %}" role="button"><i class="fa fa-upload" aria-hidden="true"></i>&nbsp SCHEDULE EPISODE</a>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
Settings.py
In the Installed Apps Add 'Bootstrap3_datetime'
template
Add The following Lines into the HTML Head Tag
{% block header %}
{% load static %}
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap /3.0.0 css/bootstrap.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.js"></script>
{{ form.media }}
{% endblock %}

Django form won't display

I'm working on a project and we need to add a form to add an event. It lists the name, date, time, and address. I got the form to work but when I added the base, the form doesn't show up on the web page with the base loaded. I'm thinking it has something to do with my html file. Here is my html file.
{% extends "base.html" %}
{% block heading %}My Events{% endblock %}
{% block content3 %}
</h1><b><font size="5">Save Event</b></h1></font>
<form method="POST" action=".">{% csrf_token %}
{{form.as_p}}
<input type ="submit" value="Add Event"/>
</form>
{% endblock %}
views:
def add_event(request):
user = request.user
events = user.event_set.all()
if request.method == "POST":
form = EventForm(request.POST)
if form.is_valid():
event = Event.objects.create(
eventname = form.cleaned_data['eventname'],
eventdate = form.cleaned_data['eventdate'],
eventtime = form.cleaned_data['eventtime'],
address = form.cleaned_data['address'],
user = request.user
)
return HttpResponseRedirect('/')
else:
form = EventForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('add_event.html',variables)
base:
HTML (base.html)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>DelMarVa Happenings | {% block title %}{% endblock %}</title>
<link rel="stylesheet" href="/site_media/style.css" type="text/css" />
</head>
<body>
<div id="wrapper">
<div id="masthead">
<div id="logo">
<img src="/site_media/Delmarva.gif" width="100px" height="80px" />
</div>
<h1>DelMarVa Happenings</h1>
<br />
<h4>A listing of events in and around Delaware, Maryland, and Virginia</h4>
</div>
<div id="nav">
{% if user.is_authenticated %}
<h3>welcome, {{ user.username }}</h3>
{% else %}
<h3>welcome, guest</h3>
{% endif %}
<ul>
<li><a href="/">home<a/></li>
{% if user.is_authenticated %}
<li>add event</li>
<li>my events</li>
<li>my account</li>
<li>logout</li>
{% else %}
<li>login</li>
<li>register</li>
{% endif %}
</ul>
</div>
<div id="ads">
<img src="/site_media/ad.jpg" />
</div>
<div id="main">
<h2>{% block head %}{% endblock %}</h2>
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
Your base.html does not have a {% block content3 %} - rename the block name in base, or the extended template to match each other.
Make sure to leave space between form.as_p and the braces. As such, {{ form.as_p }}

Categories