I have designed a model in Django and a form according to it. The below are the both files.
models.py
from django.db import models
class TotalEvent(models.Model):
CustomerID = models.CharField(max_length=30)
eventID = models.CharField(max_length=100)
eventPlace = models.CharField(max_length=100)
eventStartTime = models.TimeField(auto_now=False)
eventDate = models.DateField(auto_now=False)
forms.py
from django import forms
from django.forms import ModelForm
from catering.models import TotalEvent
class TotalEventForm(ModelForm):
class Meta:
model = TotalEvent
fields = '__all__'
Now, When in my html file I tried this:
{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
<h1>Detail page</h1>
<p>Enter your schedule details here</p>
<form method="post">{% csrf_token %}
{% for field in forms %}
{{field}}
<input type="submit" value="Submit"/>
{% endfor %}
</form>
{% endblock %}
views.py
from django.shortcuts import render
from catering.forms import TotalEvent
def add(request):
if request.method == 'POST':
form = TotalEvent(request.POST)
if form.is_valid():
form.save()
return render(request, 'index.html', { 'form': TotalEvent()
})
In the output it shows no input fields except the following output
Enter your schedule details here
Please have a look and let me know where is the error.
Use TotalEventForm instead TotalEvent as TotalEvent is model class not form class, update your views.py
def add(request):
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = TotalEventForm(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 = TotalEventForm()
return render(request, 'index.html', {'form': form})
and you can use form directly in your html file.
<form method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
type
{% for field in form %}
instead of
{% for field in forms %}
Related
I can't post in Django, because when I import an image it doesn't work for me. it tells me that there's no file selected but I selected one.
This is the post model that I created, models.py file:
class Post(models.Model):
publisher = models.ForeignKey(User,on_delete=models.CASCADE)
caption = models.CharField(max_length=100)
date_created = models.DateTimeField(default=timezone.now())
image = models.ImageField(upload_to="post_images")
def __str__(self):
return self.caption
here's the forms.py file for the Post model:
from django import forms
from .models import Post
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['caption','image']
here's the Publish function in views.py file which implements the logic for my publish feature:
#login_required
def Publish(request):
if request.method == "POST":
form = CreatePostForm(request.POST,request.FILES)
if form.is_valid():
form.publisher = request.user
form.save()
return redirect("home")
else:
form = CreatePostForm()
return render(request,"posts/publish.html",{
"form":form,
})
int the urls.py file:
from django.urls import path
from . import views
urlpatterns = [
path('publish/',views.Publish,name="publish"),
path('',views.home,name="home"),
]
and here's in html template:
{% extends "users/base.html" %}
{% load crispy_forms_tags %}
{% block title %}create{% endblock title%}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 col-md-5 authentification">
<div class="form-header">
<h1>
publish
</h1>
</div>
<div class="form-body">
<form method="POST">
<fieldset class="form-group" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary form-control">publish</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}
the Django version used is 2.2 and the Python 3.8. and Windows 10 Pro
You should alter the .publisher attribute of the .instance wrapped in the form, not the form itself, so:
#login_required
def Publish(request):
if request.method == 'POST':
form = CreatePostForm(request.POST,request.FILES)
if form.is_valid():
form.instance.publisher = request.user
form.save()
return redirect('home')
else:
form = CreatePostForm()
return render(request,'posts/publish.html',{
'form': form,
})
Since you are submitting both files and data, you should specify the enctype=… attribute [mdn] in the <form>:
<form enctype="multipart/form-data" method="POST">
…
</form>
Note: Django's DateTimeField [Django-doc]
has a auto_now_add=… parameter [Django-doc]
to work with timestamps. This will automatically assign the current datetime
when creating the object, and mark it as non-editable (editable=False), such
that it does not appear in ModelForms by default.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
So I'm making a to-do list and I made a booleanfield modelform which has attribute "complete". I want that user to check it when it's complete and I tried wriring if task.complete == True cross out the item and it didn't work(it only worked when I checked it from the admin panel). Then I tried form.complete instead of task.complete and it doesn't do anything.
models:
class Task(models.Model):
title = models.CharField(max_length=200)
complete = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
forms:
from .models import *
class TaskForm(forms.ModelForm):
title = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Add new task...'}))
class Meta:
model = Task
fields = '__all__'
html:
<div class="main-container">
<form method="POST" action="/">
{% csrf_token %}
<input type="submit"/>
{{ form.title }}
</form>
{% for task in tasks %}
{{ form.complete }}
{% if form.complete == True %}
<h1><strike>{{task.title}}</strike></h1>
{% else %}
<h1>{{task.title}}</h1>
{% endif %}
{% endfor %}
</div>
views:
def index(request):
tasks = Task.objects.order_by('-created')
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context = {
'tasks': tasks,
'form': form,
}
return render(request, 'to-do.html', context)
There are some problems with your code I don't know how to explain. Try this. It should work.
<div class="main-container">
<form method="POST" action="/"> # create new task
{% csrf_token %}
{{ form.title }}
<input type="submit" name="new-task"/>
</form>
<form method="post"> # update task status
{% csrf_token %}
{% for task in tasks %}
{% if task.complete %}
<input type="checkbox" name="if_completed" checked value="{{ task.pk }}">
<h1><strike>{{task.title}}</strike></h1>
{% else %}
<input type="checkbox" name="if_completed" value="{{ task.pk }}">
<h1>{{task.title}}</h1>
{% endif %}
{% endfor %}
<input type="submit" name="update-task"/>
</form>
</div>
view.py (Only for form, add your other code with it)
from django.http import HttpResponseRedirect
from django.urls import reverse
def index(request):
tasks = Task.objects.order_by('-created')
form = TaskForm()
if request.method == 'POST':
if 'new-task' in request.POST:
form = TaskForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('home')) # replace home with url name where you want to redirect
elif 'update-task' in request.POST:
task_pk = request.POST.getlist("if_completed")
for i in task_pk:
Task.objects.filter(pk=i).update(complete=True) # I have replace pk with i here
return HttpResponseRedirect(reverse('home')) # replace home with url name where you want to redirect
context = {
'tasks': tasks,
'form': form,
}
return render(request, 'to-do.html', context)
in forms.py
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ('title',)
widgets = {
'title': forms.TextInput(attrs={'placeholder':'Add new task...'})
}
This should work. There may be be some error because of typos or indentation. Let me know if you get any issue
def index(request):
tasks = Task.objects.order_by('-created')
form = TaskForm()
context = {
'tasks': tasks,
'form': form,
}
if request.method == 'POST':
if 'new-task' in request.POST:
form = TaskForm(request.POST)
if form.is_valid():
form.save()
elif 'update-task' in request.POST:
task_pk = request.POST.getlist("if_completed")
for i in task_pk:
Task.objects.filter(pk=pk).update(complete=True)
return render(request, 'to-do.html', context)
I have these two functions, one of them (first one) adds a new entry and the second one edits the entry:
def add_entry(request):
if request.method == 'POST':
form = AddForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
if util.get_entry(title) is None:
util.save_entry(title, content)
return redirect('entry', title)
else:
return render(request, "encyclopedia/add_entry.html", {
"form": AddForm(),
"title": title
})
return render(request, "encyclopedia/add_entry.html", {
"form": AddForm()
})
def edit_entry(request, title):
content = util.get_entry(title)
if request.method == 'POST':
form = AddForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return redirect('entry', title)
return render(request, "encyclopedia/edit_entry.html", {
"title": title,
"content": content
Here is my edit_entry.html page:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit page
{% endblock %}
{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
{% csrf_token %}
<h5>Title</h5>
<input type="text" value="{{ title }}">
<h5>Content</h5>
<textarea cols="30" rows="10">{{ content }}</textarea>
<input type="submit" value="Save Editing">
</form>
{% endblock %}
This is add_entry.html template
{% extends "encyclopedia/layout.html" %}
{% block title %}
Add new entry
{% endblock %}
{% block body %}
<h1>Create a new page</h1>
{% if title %}
<h6 style="color: red;">"{{title}}" page is already exists. Please, enter a different title</h6>
{% endif %}
<form action="{% url 'add_entry' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create">
</form>
{% endblock %}
And here is my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:title>", views.entry, name="entry"),
path("search", views.search, name="search"),
path("add_entry", views.add_entry, name="add_entry"),
path("wiki/<str:title>/edit_entry", views.edit_entry, name="edit_entry")
]
My entry view:
def entry(request, title):
if title not in util.list_entries():
return render(request, "encyclopedia/error.html", {
"error": "Page Not Found",
"query": title
})
else:
return render(request, "encyclopedia/entry.html", {
"entry": markdown2.markdown(util.get_entry(title)),
"title": title
})
The issue here when I click to save the content of the page doesn't change, I want to save the edits and display it with new content. Instead, it returns an old form with the old content (like doesn't change).
EDIT: based on your comments, I think it is better to start over.
Since you are doing some simple create and update, it maybe better to use generic views. Here is an example.
1.First and formost, you need a model.
in models.py,
from django.db import models
class Entry(models.Model):
title = models.CharField(max_length=200)
content = models.TextField(max_length=2000)
2. in your forms.py
Note: this is not necessary if you want to just use django default form. Because class-based generic views will automatically generate forms for you. However, if you need to add widget, or to add attributes (for example, add css class or id), you need to generate a customform.
from django import forms
from .models import Entry
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ('title', 'content')
widgets = {
'title': forms.TextInput(attrs={'placeholder': 'Title'}),
'content': forms.TextInput(attrs={'class': 'content'}),
}
3. views.py
from .models import Entry
from django.views.generic.edit import CreateView, UpdateView
class CreateEntry(CreateView):
model=Entry
template_name = 'create_edit_entry.html' # this is the template, you might need to change its path.
form_class= EntryForm # this is added because we are using customform
success_url = '/' #this can be changed
class UpdateEntry(UpdateView):
model=Entry
template_name = 'create_edit_entry.html'
form_class= EntryForm
4. urls.py
from django.urls import path
from .views import CreateEntry, UpdateEntry
urlpatterns = [
path('entry/', CreateEntry.as_view(), name='create_entry'),
path('entry/<int:pk>', UpdateEntry.as_view(), name='update_entry'),
]
5. admins.py
from django.contrib import admin
from .models import Entry
class EntryAdmin(admin.ModelAdmin):
list_display = (('id', 'title', 'content'))
admin.site.register(Entry, EntryAdmin)
6. templates (create_edit_entry.html)
{% extends 'base.html' %}
{% block extrahead %}
{% load static %}
{% endblock %}
{% block content %}
<form action="." method="POST">
{% csrf_token %}
{{ form }}
<button type="submit">SUBMIT</button>
</form>
{% endblock %}
After you update all these files and update mysite/urls.py, you will 1) open http://127.0.0.1:8000/entry to add an entry. Check if the entry is created in your admin page. 2) then you will open http://127.0.0.1:8000/entry/1 (if the id=1) to see if your original entry is shown. 3) then you will update the form, and check if the update is successful or not in your admin.
This backbone should be able to get you started. Note that I did not put DetailView, ListView, so you need to check if the object is created and updated in your admin page. Of cause, you can add DetailView and ListView by yourself (check out django document here to learn more about generic views).
**************************************earlier answer **************
1. First thing first, it is always helpful to access form.errors when you are having trouble with forms. What you do is to add else: print(form.errors) like the following:
if form.is_valid():
# other code
else:
print(form.errors)
2.
Your edit_entry.html change to something like below: I guess you wanted use your own styling (add Title, Content etc) to the form, so you did not use {{form}}. If what I suggest worked, you can add form styling later.
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit page
{% endblock %}
{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
{% csrf_token %}
{{form}}
</form>
{% endblock %}
3. your edit_entry view:
def edit_entry(request, title):
entry = get_object_or_404(Entry, title=title) # i assume your Model name is "Entry"
if request.method == 'POST':
form = AddForm(request.POST, instance = entry)
if form.is_valid():
print('under form.is_valid) # add this line to keep track
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
form.save()
return redirect('entry', title=entry.title)
else:
print(form.errors)
else:
form = AddForm(instance = entry)
return render(request, "encyclopedia/edit_entry.html", {
'form': form})
error messages are not working in Django templates.
after add error code in html template it shows no error message in webapp when fields are empty and press on submit button. html5 error is "novalidate" in template.
ValueError at /signup/
The view blog.views.user_signup didn't return an HttpResponse object. It returned None instead.
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, UsernameField
from django.contrib.auth.models import User
from django.utils.translation import gettext,gettext_lazy as _
class SignUpForm(UserCreationForm):
password1 = forms.CharField(label='Password',widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2 = forms.CharField(label='Confirm Password(again)',widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields = ['username','first_name','last_name','email']
labels = {'username':'Username','first_name':'First Name','last_name':'Last Name','email':'Email'}
widgets = {'username':forms.TextInput(attrs={'class':'form-control'}),
'first_name':forms.TextInput(attrs={'class':'form-control'}),
'last_name':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),}
class LoginForm(AuthenticationForm):
username = UsernameField(widget=forms.TextInput(attrs={'autofocus':True, 'class':'form-control'}))
password = forms.CharField(label=_('password'),strip=False, widget=forms.PasswordInput(attrs={'autocomplete':'current-password','class':'form-control'}))
signup.html
{% extends 'blog/base.html' %}
{% load static %}
{% block content %}
<div class="col-sm-10">
<h3 class="text-white my-5">Signup Page</h3>
<form action="" class="post" novalidate>
{% csrf_token %}
{% for fm in form %}
<div class="form-group">
{{fm.label_tag}} {{fm}} {{fm.errors | striptags}}
</div>
{% endfor %}
<input type="submit" value='Submit' class='btn btn-primary'>
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p> {{error}} </p>
{% endfor %}
{% endif %}
</form>
</div>
{% endblock content %}
views.py
from django.shortcuts import render,HttpResponseRedirect
from django.contrib import messages
# Create your views here.
# home
def home(request):
return render(request, 'blog/home.html')
# about
def about(request):
return render(request, 'blog/about.html')
# contact
def contact(request):
return render(request, 'blog/contact.html')
# Dashboard
def dashboard(request):
return render(request, 'blog/dashboard.html')
# Logout
def user_logout(request):
return HttpResponseRedirect('/')
# Signup
def user_signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
messages.success(request, 'Congratulations You have become an Author.')
form.save()
else:
form = SignUpForm()
return render(request, 'blog/signup.html',{'form':form})
# Login
def user_login(request):
form = LoginForm()
return render(request, 'blog/login.html', {'form':form})
You need to handle GET and POST request :
def user_signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
messages.success(request, 'Congratulations You have become an Author.')
form.save()
else:
form = SignUpForm()
return render(request, 'blog/signup.html',{'form':form})
Please make sure to use POST method in your html :
<form action="" method="POST" class="post" novalidate>
...
</form>
Hi guys I am new to Django.
I wants that when I login to my account there is a edit button which shows me a form of some fields which I can edit.
I am confused how the data is saved to the same user profile.
So can anybody tell me how is that possible.Can show me it with one example
With my profile.html I can see my profile and on click on edit button I can edit my profile
{% extends 'base.html' %}
{% block content %}
<p>User_id: {{ drinker.user_id }}
<p>Name: {{ drinker.name }}</p>
<p>Birthday: {{ drinker.birthday }}</p>
<p>first_name: {{ user.first_name }}</p>
<p>Users: {{ user.username }}</p>
<p>Edit Profile
{% endblock %}
Edit function
def Edit(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
drinker = request.user.get_profile()
context = {'drinker':drinker}
return render_to_response('edit.html', context, context_instance=RequestContext(request))
**Edit.html**
{% extends "base.html" %}
{% block extrahead %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js" type="text/javascript"></script>
<script>
$(function() {
$( "#birth" ).datepicker();
});
</script>
{% endblock %}
{% block content %}
<form action="/edit1/" method="post">
{% csrf_token %}
<div class="register_div">
<p><label for="name">Name:</label></p>
<p><input type="text" value="{{ drinker.name }}"></p>
</div>
<div class="register_div">
<p><label for="birthday">Birthday: {{ drinker.birthday }} </label></p>
<p>Choose new date of birth</p>
<p><input type="text" value="" id="birth"></p>
</div>
<p><input type="submit" value="submit" /></p>
</form>
{% endblock %}
On edit1 edit request function works
def EditRequest(request):
#if request.method == 'POST':
#form = UserProfileForm(request.POST, instance=user)
#if request.user.is_authenticated():
#return render_to_response('hgdhg')
if request.method == 'POST':
form = EditForm(request.POST)
if form.is_valid():
user=User.objects.create_user(usere_id=form.cleaned_data['user_id'])
#user.save()
drinker=user.get_profile()
drinker.name=form.cleaned_data['name']
drinker.birthday=form.cleaned_data['birthday']
drinker.save()
return HttpResponseRedirect('/profile/')
else:
return HttpResponseRedirect('/f/')
else:
return render_to_response('f')#,{'form':form} , context_instance=RequestContext(request))
this editrequest doesn't work ?
Here are the steps you need to execute to edit a user's profile:
Find out which user is logged in (read up on user authentication)
Check if the user has a profile or not; use the normal django query mechanism for that.
If the user has a profile; populate a ModelForm with the instance of the profile (see this page in the manual)
Display the form to the end user just like any other form.
When the user submits changes, do the normal form validation and save the object to the database.
Here is some code that does steps 1-4:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from myapp.models import UserProfile
from myapp.forms import UserProfileForm
#login_required
def edit_profile(request):
try:
user_profile = UserProfile.objects.get(user=request.user)
except UserProfile.DoesNotExist:
# this user has no profile
return redirect('/error')
user_profile_form = UserProfileForm(instance=user_profile)
return render(request,'profile_edit.html',{'form':user_profile_form})
The UserProfileForm class:
from django import forms
from myapp.models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
pass the instance of user along your model form
user = User.objects.get(user_name = username)
form = Registrationform(instance=user)
and render this form to your template
Example i did before:
#login_required
def lexuseditform(request,userpk):
if Adult.objects.filter(user=request.user).exists():
adult = Adult.objects.get(user=request.user) # load existing Adult
else:
adult = Adult(user=request.user) # create new Adult
if request.method == 'POST': # If the form has been submitted...
form = AdultForm(request.POST,instance=adult) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
form.save()
redirect_url = reverse('lexusedited',kwargs={'userpk': request.user.pk})
return HttpResponseRedirect(redirect_url) # Redirect after POST
else:
form = AdultForm(instance=adult) # An unbound form
return render(request,'lexus/lexuseditform.html', {'form': form})
#login_required
def lexusedited(request,userpk):
return render(request,'lexus/lexusedited.html')
Hope this helps...