i am new to django when i try to run this project i wasn't getting any input fields in my template current page was only showing the given labels
i don't know where i've gone wrong
can any of you guys help??
these are my models.py file
from django.db import models
# Create your models here.
class Student(models.Model):
sid = models.CharField(max_length=100)
sname = models.CharField(max_length=100)
sclass = models.CharField(max_length=100)
semail = models.EmailField(max_length=100)
srollnumber = models.CharField(max_length=100)
scontact = models.CharField(max_length=100)
saddress = models.CharField(max_length=100)
class Meta:
db_table = "student"
the are my forms.py file
from django import forms
from student.models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = "__all__"
these are my views.py file
from django.shortcuts import render
from student.models import Student
from student.forms import StudentForm
def student_home(request):
return render(request, 'employee/dash.html')
def add_student(request):
if request.method == "POST":
form = StudentForm(request.POST)
if form.is_valid():
try:
form.save()
return render(request, 'employee/dash.html')
except:
pass
else:
form = StudentForm()
return render(request, 'student/addstudent.html')
template
<!DOCTYPE html>
<html lang="en">
<head>
<title>addstudent</title>
</head>
<body>
<a href="/home" >home</a>
<form method="POST" action="/add_student">
{% csrf_token %}
<label>Student ID:</label>
{{ form.sid }}
<label>Name :</label>
{{ form.sname }}
<label>Class :</label>
{{ form.sclass }}
<label>Email ID:</label>
{{ form.semail }}
<label>Roll Number :</label>
{{ form.srollnumber }}
<label>Contact :</label>
{{ form.scontact }}
<label>Address :</label>
{{ form.saddress }}
<button type="submit">Submit</button>
</form>
</body>
</html>
You forget to give the context to the render function:
return render(request, 'student/addstudent.html',context={'form':form})
should work
You have not included any context in your render functions. Your view should be:
def add_student(request):
if request.method == "POST":
form = StudentForm(request.POST)
if form.is_valid():
try:
form.save()
return render(request, 'employee/dash.html', context={'form': form})
except:
pass
else:
form = StudentForm()
return render(request, 'student/addstudent.html', context={'form': form})
Related
i made a blog site sometime ago with python and django and used mysql as a database
the viewers can see all written blogs and comments ,but to write blogs and comments viewers have to login or signup ...thats all good but the problem is that when i want to edit or delete a blog or comment , any logged-in user can edit or delete any comment or blog , i want to implement user permissions so that only the user who wrote the blog /comment can edit /delete it ,not every one
my views
from django.shortcuts import render,redirect
from django.contrib.auth.models import User,auth
from django.contrib import messages
from app.models import signup,blog
from app.forms import CommentForm,Blogform
# Create your views here.
def signup1(request):
if request.method == "POST":
Realname = request.POST['realname']
Username = request.POST['username']
sEmail = request.POST['semail']
sPassword = request.POST['spassword']
if User.objects.filter(username=Username).exists():
messages.info(request, "user exists")
return redirect("/")
else:
user = User.objects.create_user(username=Username, email=sEmail, password=sPassword, first_name=Realname)
user.save()
auth.login(request, user)
print("user made")
return redirect("/")
else:
form1 = signup.objects.all()
return render(request, 'Signup.html', {'signup': form1})
def login(request):
if request.method == "POST":
username =request.POST['lgusername']
password =request.POST['lgpassword']
user =auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect("/")
else:
messages.info(request,"invalid username or password")
return redirect("/login")
else:
return render(request,"login.html")
def logout(request):
auth.logout(request)
return redirect("/")
def blog1(request):
blogs= blog.objects.all()
return render(request,'blog.html',{'blogs':blogs})
def blogdetail(request ,slug):
post =blog.objects.get(slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('post_detail', slug=post.slug)
else:
form = CommentForm()
return render(request,'blog_detail.html',{'post':post ,'form': form})
def writeblog(request):
if request.method == "POST":
form=Blogform(request.POST)
if form.is_valid():
try:
form.save()
return redirect('/')
except:
pass
else:
form=Blogform()
return render(request,"write.html",{'form':form})
def edit(request,slug):
edit =blog.objects.get(slug=slug)
return render(request,"edit.html",{'edit':edit})
def update(request,slug):
edit = blog.objects.get(slug=slug)
form = Blogform(request.POST, instance=edit)
if form.is_valid():
form.save()
return redirect("/")
return render(request, 'update.html', {"edit" :edit})
def delete(request,slug):
delete= blog.objects.get(slug=slug)
delete.delete()
return redirect('/')
////this is my template
{% extends "base.html" %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>blog</title>
</head>
<body>
{%block content%}
<div class="container">
<div class="d-flex align-items-center col-lg-12 col-md-12 col-sm-10 flex-column">
{% for blogs in blogs %}
<div style="width:100%;" class="border mt-3 border-secondary rounded">
<div class="container">
<h2 style="font-size:35px;" class="mr-auto rounded bg-secondary mt-2 pl-3 pb-2 pt-1 ">{{blogs.title}}</h2>
</div>
<small style="margin-left:4%;margin-bottom:4px;">posted at {{blogs.date_added}}</small>
<p style="margin-left:4%;margin-bottom:4px;"><strong>{{blogs.intro}}</strong></p>
<a style="margin-left:90%;" href="{% url 'post_detail' blogs.slug %}">Read more</a>
</div>
{% endfor %}
</div>
</div>
<a class="btn btn-primary" data-bs-toggle="offcanvas" href="#toggle" role="button" aria-controls="sidebar">
Link with href
</a>
<div class="offcanvas offcanvas-start" id="toggle">
<div class="offcanvas-header">
<h5 class="offcanvas-title"> Hello This is my offcanvas</h5>
<button type="button" class="btn-close" aria-label="sidebar-lable" data-bs-dismiss="offcanvas" ></button>
</div>
<div class="offcanvas-body">
<p>
this is the body of the offcanvas that i made just five minutes ago .
hello again
bye .
</p>
<form class="form-group ">
<label>Type your name</label>
<input placeholder="your name" class="form-control" type="text"><br>
<input type="submit" class="btn btn-outline-success">
</form>
</div>
</div>
{%endblock%}
</body>
</html>
my urls
from django.urls import path
from . import views
urlpatterns=[
path('signup',views.signup1,name="signup"),
path('login',views.login,name="login"),
path('logout',views.logout,name="logout"),
path('',views.blog1,name="blog"),
path('write',views.writeblog,name='write')
]
my models
from django.db import models
# Create your models here.
class signup(models.Model):
Realname = models.CharField(max_length=100)
Username = models.CharField(max_length=100)
sEmail = models.EmailField(max_length=150)
sPassword = models.CharField(max_length=250)
class Meta:
db_table ="Signupusers"
def __str__(self):
return self.Realname
class blog(models.Model):
title =models.CharField(max_length=250)
slug =models.SlugField()
intro =models.TextField()
body= models.TextField()
writer=models.TextField()
date_added=models.DateTimeField(auto_now_add=True)
class Meta:
db_table="blog1"
ordering =['-date_added']
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(blog, related_name='comments', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
email = models.EmailField()
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
db_table="comments"
ordering = ['date_added']
I am trying to work on a django-based project/website that logs who took out our dogs last. I am very new to django so please bear with lack of knowledge in the field. I currently have my project set up so that I have models based on users/family members, the families' dogs, posts (logs of when and who took out the dogs), and actions, which is a child class that uses the dog and post models as foreign keys to see if the dogs peed and or pooped when they were taken out. The part that I am stuck on is trying to figure out how I create the post form. Since we have two dogs I need the form/post page to display a set of check boxes (for peeing and pooping actions) for each dog model that exists. While I can successfully display one action set, I run into the difficulty of trying to display the correct number of action sets and also to post the set of actions and the post itself. I have been trying to work with the formset_factory function but I am confused as to how I get it to function properly. Can anyone help? I have been stuck on this problem for quite a while and any support would be greatly appreciated.
models.py:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Dog(models.Model):
name = models.CharField(max_length = 20)
class Post(models.Model):
walker = models.ForeignKey(User, on_delete = models.CASCADE)
time_posted = models.DateTimeField(default = timezone.now)
issues = models.TextField(max_length = 300)
class Action(models.Model):
post = models.ForeignKey(Post, on_delete = models.CASCADE)
dog = models.ForeignKey(Dog, on_delete = models.CASCADE)
peed = models.BooleanField(default = False)
pooped = models.BooleanField(default = False)
forms.py:
from django import forms
from django.forms import formset_factory
from dog_log_app.models import *
class Log_Form(forms.ModelForm):
class Meta:
model = Post
fields = ("issues",)
class Action_Form(forms.Form):
peed = forms.BooleanField(initial = False, required = False)
pooped = forms.BooleanField(initial = False, required = False)
views.py:
from django.shortcuts import render
from django.forms import formset_factory, modelformset_factory
from .models import Post, Dog, Action
from dog_log_app.forms import *
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect
def home(request):
context = {
'posts': Post.objects.all().order_by('-time_posted'),
'actions': Action.objects.all(),
'dogs': Dog.objects.all()
}
return render(request, 'dog_log_app/home.html', context)
def post(request):
form_post = Log_Form(request.POST or None)
form_actions = modelformset_factory(Action, fields = ('peed', 'pooped'), extra = Dog.objects.count())
if request.method == 'POST':
form_post = Log_Form(request.POST)
if form_post.is_valid() and form_actions.is_valid():
post_save = form_post.save(commit = False)
post_save.walker = request.user
post_save.save()
form_actions.save()
return HttpResponseRedirect('..')
context = {
'post': form_post,
'action': formset_factory(Action_Form, extra = Dog.objects.count()),
'dogs': Dog.objects.all()
}
return render(request, 'dog_log_app/post_form.html', context)
post_form.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Post</title>
</head>
<body>
<div>
<form method="POST">
{% csrf_token %}
<fieldset>
<legend>Create Post</legend>
<h3>{{dogs.name}}</h3>
<p>{{action.as_p}}</p>
<p>{{post.as_p}}</p>
</fieldset>
<div>
<button type="submit" value="Ok">Post</button>
</div>
</form>
</div>
</body>
</html>
what you can try would be to use ajax to add the amount you want, what I usually do is use the form:
from django.forms import ModelForm
from django.forms.models import inlineformset_factory
class PostForm(ModelForm):
class Meta:
model = Post
fields = (
'issues',
)
class ActionForm(ModelForm):
class Meta:
model = Action
fields = (
'peed', 'pooped'
)
ActionFormSet = inlineformset_factory(
Post, Action, form=ActionForm,
fields = ['peed', 'pooped'], extra=1, can_delete=True,
)
With the forms created, we move on to the views, which will be class-based for convenience:
from django.db import transaction
from django.views.generic import CreateView, UpdateView
from .models import Post
from .forms import PostForm, ActionFormSet
class PostCreateView(CreateView):
template_name = 'your template'
form_class = PostForm
success_url = reverse_lazy('your url')
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['formset'] = ActionFormSet(self.request.POST)
else:
data['formset'] = ActionFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
formset = context['formset']
with transaction.atomic():
self.object = form.save()
if formset.is_valid():
formset.instance = self.object
formset.instance.walker = self.request.user
formset.save()
return super().form_valid(form)
class PostUpdateView(UpdateView):
template_name = 'your template'
form_class = PostForm
model = Post
success_url = reverse_lazy('your url')
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['formset'] = ActionFormSet(
self.request.POST, instance=self.object)
else:
data['formset'] = ActionFormSet(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
formset = context['formset']
with transaction.atomic():
self.object = form.save()
if formset.is_valid():
formset.instance = self.object
formset.save()
return super().form_valid(form)
and to display the information you can use a jquery library for the dynamic information on saving:
enter link description here
With that the configuration is much easier
An example template would be:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container">
<div class="card">
<div class="card-content">
<h2>Agregar Proyecto</h2>
<div class="col-md-4">
<form id="form-container" method="post">
{% csrf_token %}
{{ form }}
<h2>Actions</h2>
<table>
{{ formset.management_form }}
{% for form in formset %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr id="projects_data">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<button type="submit" class="btn btn-success">{{ message }}</button>
Cancel
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function () {
$('#projects_data').formset({
prefix: '{{ formset.prefix }}',
addText: 'create',
deleteText: 'remove',
});
})
</script>
{% endblock %}
and in that way add data dynamically.
I'm trying to create a form for edit table Person, but in this form field Car must be filtered by selected Company. I'm very new to python/django so this may be a bad approach, high level suggestions welcome. Here is what I have:
I have 3 models in models.py:
from django.db import models
class Company(models.Model):
company = models.CharField(max_length=25)
def __str__(self):
return self.company
class Car(models.Model):
car = models.CharField(max_length=25)
company = models.ForeignKey(Company, on_delete = models.CASCADE)
def __str__(self):
return self.car
class Person(models.Model):
name = models.CharField(max_length=20)
car = models.ForeignKey(Car, on_delete = models.CASCADE)
def __str__(self):
return self.name
views.py:
def index(request):
people = Person.objects.all().select_related('car__company')
table = PersonTable(people)
return render(request, 'index.html', {'table': table})
def edit(request, id):
person = Person.objects.get(id = id)
car = Car.objects.get(id = person.car_id)
company = Company.objects.get(id = car.company_id)
if request.method == 'POST':
form = PersonForm(car.company_id, request.POST, instance=person)
if form.is_valid():
form.save()
return redirect('/person/')
else:
companys = CompanyForm(instance=company)
form = PersonForm(car.company_id, instance=person)
return render(request, 'person/edit.html', {'companys':companys, 'form':form})
def Company_select(request):
if request.method == 'POST':
form = CompanySelectForm(request.POST)
if form.is_valid:
return redirect('/person/edit/1/') # Return to form PersonForm with id=1.
# How to return selected Company?
# How to return to page with other id?
else:
form = CompanySelectForm()
return render(request, 'person/company_select.html', {'form':form})
urls.py:
app_name = 'person'
urlpatterns = [
path('edit/<int:id>/', views.edit),
path('company/', views.Company_select, name='company'),
path('', views.index),
]
forms.py
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ('company',)
class CompanySelectForm(forms.Form):
company = forms.ModelChoiceField(queryset=Company.objects.all().order_by('company'))
class Meta:
fields = ('company',)
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('name', 'car',)
def __init__(self, company, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
self.fields['car'].queryset = Car.objects.filter(company=company) #Filter by Company
edit.html
{% extends "base.html" %}
{% block header %}Edit{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
{{ companys.as_table }}
<button type="button" class="btn btn-default btn-xs">Select Company</button>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
company_select.html
{% extends "base.html" %}
{% block header %}Select Company{% endblock header %}
{% block content%}
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</form>
{% endblock content %}
This is my proposition : tested
form.py => add attribut that will call a JS function defined in your .html
class PersonForm(ModelForm):
class Meta:
model = Person
fields = ('name', 'company', 'car')
def __init__(self, *args, **kwargs,):
super(PersonForm, self).__init__(*args, **kwargs)
class SelectForm(Form):
name = CharField(label='name')
company = ChoiceField(label='company')
car = ChoiceField(label='car')
class Meta:
fields = ('name', 'company', 'car', )
def __init__(self, cars=None, *args, **kwargs, ):
super(SelectForm, self).__init__(*args, **kwargs)
self.fields['car'].choices = cars
self.fields['company'].choices = tuple(Company.objects.all().values_list(flat=False))
self.fields['company'].widget.attrs['onchange'] = "load_car()"
edit.html: => define the JS function
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id='myform' method="POST">
{% csrf_token %}
{{ form }}
</form>
<button class="btn btn-primary" type="submit" name="submit">submit</button>
</body>
<script>
function load_car()
{
document.getElementById('myform').action = "/stack/myview";
document.getElementById("myform").submit();
}
</script>
</html>
Views.py:=> new view that will look for the company name in the database and return to the template
def index(request): # RF configuration FORM
form = PersonForm()
content = {'form': form}
return render(request, 'stack/index.html', content)
def edit(request, my_id):
if request.method == 'POST':
form = PersonForm(request.POST)
if form.is_valid():
form.save()
# Do ....
return HttpResponseRedirect(reverse('stack:index'))
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in
list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
else:
person = Person.objects.values_list().get(id__exact=my_id)
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=person[2]).values('car'))]
form = SelectForm(cars=cars, initial={'name': person[1], 'company': person[2], 'car': person[3]})
content = {'form': form}
return render(request, 'stack/edit.html', content)
def myview(request):
cars = []
[cars.append((x['car'], x['car'])) for x in list(Car.objects.filter(company__exact=request.POST['company']).
values('car'))]
form = SelectForm(cars=cars, initial={'name': request.POST['name'], 'company': request.POST['company'], 'car': None})
content = {'form': form}
return render(request, 'stack/edit.html', content)
I install django-smart-selects
In models.py:
from smart_selects.db_fields import ChainedForeignKey
...
class Person(models.Model):
name = models.CharField(max_length=20)
company = models.ForeignKey(Company, on_delete = models.CASCADE)
car = ChainedForeignKey(
Car,
chained_field="company",
chained_model_field="company",
show_all=False,
auto_choose=True,
sort=True,
on_delete=models.CASCADE,
blank=True,
null=True)
def __str__(self):
return self.name
I make comments on the site and cannot understand why, after the user has filled out comment forms, they are not displayed, I try to display them through a template
P.S
I need to display the text and the nickname that the user would enter
views.py
def CommentGet(request):
if request.method == 'POST':
comment = Comments(request.POST)
name = request.POST['name']
text = request.POST['text']
if comment.is_valid():
comment.save()
return HttpResponseRedirect(request.path_info)
comments = CommentModel.objects.all()
else:
comment = Comments(request.POST)
comments = CommentModel.objects.all()
return render(request, 'news/post.html', {'comment': comment,'comments':comments})
post.html
<form method="post" action="{% url 'comment' %}">
{% csrf_token %}
<input type="text" name="name" value="{{ name }}">
<input type="text" name="text" value="{{ text }}">
<input type="submit">
</form>
{% for comm in comments %}
<h1> {{ comm.name }} </h1>
<h1> {{ comm.text }} </h1>
{% endfor %}
models.py
class CommentModel(models.Model):
name = models.CharField(max_length=100)
text = models.TextField(default='')
dates = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-dates']
def __str__(self):
return self.name
I'd suggest using a ModelForm to make things simpler, Try something like this:
# views.py
def CommentGet(request):
if request.method == 'POST':
comment_form = CommentForm(request.POST)
comment_form.save()
else:
comment_form = CommentForm()
comments = CommentModel.objects.all()
return render(request, 'news/post.html', {'comment_form': comment_form,'comments':comments, })
# forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = CommentModel
fields = ['name', 'text']
Then, in your template, replace the two text fields with {{ comment_form }}
When I trying to add image from admin panel all OK, but when I trying to add image from site, I have this error: image of error. When I trying to post Detail without image, I have the same problem. Before this wasn't.
views.py:
def new_detail(request):
if request.user.is_authenticated:
if request.user.is_superuser:
if request.method == 'POST':
car = request.POST['car']
author = request.user
detail = request.POST['detail']
price = request.POST['price']
description = request.POST['description']
image = request.FILES['images']
detail = Detail(car = car, author = author, detail = detail, price = price, description = description, images = image)
detail.save()
return redirect('/new_detail/')
else:
return redirect('/login/')
return render(request, 'shop/new_detail.html')
new_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-8">
<div class=".signin">
<form action="" method="POST">
{% csrf_token %}
<h3>Автомобіль: </h3>
<select name="car">
<option selected>Audi A8 D2 3.3 TDI</option>
<option>Audi A8 D2 3.7</option>
...
...
...
<h3>Ціна: </h3><textarea name="price"></textarea>
<h3>Фотки: </h3><input type="image" name="images" />
<p>
<input type="submit" value="Опублікувати" />
</form>
</div>
</div>
</div>
models.py:
from django.db import models
class Detail(models.Model):
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,)
car = models.CharField(max_length=100)
detail = models.TextField()
description = models.TextField()
price = models.CharField(max_length=30)
images = models.ImageField(upload_to='details', null = True, blank = True)
def __unicode__(self):
return self.detail
def __str__(self):
return self.detail
The first problem is that you are missing enctype="multipart/form-data" from your form tag in the template. See the docs on file uploads for more info.
<form action="" method="POST" enctype="multipart/form-data">
Secondly, your view doesn't handle the case when data is missing from the form. Instead of doing request.POST['detail'] you should be checking if 'detail' in request.POST or using request.POST.get('detail').
However it would be very time consuming to check every field individually. You should look at Django forms and model forms, which can handle a lot of this for you.
from django import forms
class DetailForm(forms.ModelForm):
class Meta:
model = Detail
fields = ['car', 'author', 'detail', 'price', 'description', 'images']
Then your view will be something like
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(lambda u: u.is_superuser)
def new_detail(request):
if request.method == 'POST':
form = DetailForm(request.POST)
if form.is_valid():
detail = form.save()
return redirect('/new_detail/')
else:
form = DetailForm(request.POST)
return render(request, 'shop/new_detail.html', {'form': form})
You can use the form to simplify your template as well:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
See the docs on rendering fields manually if you need more control in the template.