Django form is not showing up - python

Here is my forms.py
from django import forms
class EmailForm(forms.Form):
from_ = forms.EmailField(max_length=50)
Here is my views.py
from django.shortcuts import render
from .forms import EmailForm
def index(request):
return render(request, "base.html")
def emailSender(request):
form = EmailForm()
return render(request, "base.html", {"form" : form})
And finally here is my html template
<form id="form" method="post">
{% csrf_token %}
{{ form }}
<div class="form-outline mb-4">
<label class="form-label" for="from">From:</label>
{{ form.from_ }}
</div>
Any of my {{ form }} does not work. When I check the inspect tab they both are not created so I think this isn't some css problems here.

Tried the form code in shell , seems to be working ,try the following edits:
use a clear name to the field in forms.py
from django import forms
class EmailForm(forms.Form):
email = forms.EmailField(max_length=50)
Fix the html template (don't forget to close the form, I suppose you're taking proper care of other html tags: html, head, body, ...)
<form method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>

Related

Django: What do I need to do to get the csv file to actually load into the model?

I am having a problem getting my upload.html to be fully functional. The html page shows okay and I can even select an csv file for upload. It does not do anything when clicking on the "Add data" button. What do I need to do to get the csv file to actually load into the model. Below is the code for upload.html shown below:
{% extends "myapp/base.html" %}
{% load bootstrap5 %}
{% block body_block %}
<div class="container">
<h1>Please select csv file for upload</h1>
<form action="" method="POST" enctype="multipart/form-data" class="form-control" >
{% csrf_token %}
{{ form }}
</form>
<button type="submit" class="btn btn-primary">Add data</button>
</div>
{% endblock %}
Below is the forms.py
from django import forms
from .models import Csv
class CsvForm(forms.ModelForm):
class Meta:
model = Csv
fields = ('file_name',)
Below is the views.py
from django.shortcuts import render
from .forms import CsvForm
from .models import Csv
import csv
def upload_file_view(request):
form = CsvForm(request.POST or None, request.FILES or None)
# check whether it's valid:
if form.is_valid():
form.save()
form = CsvForm()
obj = Csv.objects.get(activated=False)
with open(obj.file_name.path, 'r') as f:
reader = csv.reader(f)
for row in reader:
# this is not working yet.
print(row)
obj.activated=True
obj.save()
context = {'form': form,}
return render(request, 'csvs/upload.html', context)
below is the models.py
from django.db import models
class Csv(models.Model):
file_name = models.FileField(upload_to='csvs/', max_length=100)
uploaded = models.DateTimeField(auto_now_add=True)
activated = models.BooleanField(default=False)
def __str__(self):
return "File id: {}".format(self.id)
I don't understand the code completely. Can the csv be located in any directory when selecting it?
So the Upload.html file has the button outside the block. So it has to change to inside the form tag like below.
{% extends "myapp/base.html" %}
{% load bootstrap5 %}
{% block body_block %}
<div class="container">
<h1>Please select csv file for upload</h1>
<form action="" method="POST" enctype="multipart/form-data" class="form-control" >
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-primary">Add data</button>
</form>
</div>
{% endblock %}

Blogs disappear when post is liked

the code is working without any issues but the problem is that after I like a post instead of the like button changing the entire for loop having the posts stops functioning. ie there is nothing displayed other than the users username. The server doesn't throw any particular error it just doesn't display the for loop. I feel its an issue with the render part but I'm not quite sure what exactly is wrong with it
below are my files
views.py
from django.shortcuts import render,get_object_or_404
from django.views.generic import ListView
from .models import Blog
from django.http import HttpResponseRedirect
class BlogsList(ListView):
model=Blog
template_name='blog/home.html'
context_object_name='blogs'
ordering=['-date_posted']
def like_post(request, blog_id):
post = get_object_or_404(Blog, id=blog_id)
is_liked=False
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
is_liked=False
else:
post.likes.add(request.user)
is_liked=True
context={
'is_liked':is_liked
}
return render(request, 'blog/home.html', context)
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 Blog(models.Model):
title=models.CharField(max_length=100)
content=models.TextField()
date_posted=models.DateTimeField(default=timezone.now)
author=models.ForeignKey(User, on_delete=models.CASCADE)
likes=models.ManyToManyField(User,related_name='likes',blank=True)
def __str__(self):
return self.title
def get_absolute_url():
return reverse('blog-home')
urls.py
from django.urls import path
from . import views
urlpatterns=[
path('',views.BlogsList.as_view(),name='blog-home'),
path('<int:blog_id>/like/', views.like_post, name='like_post')
]
and home.html
{{ user.username }}
{% block content %}
{% for post in blogs %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<h2>{{ post.author }}</h2>
<small class="text-muted">{{ post.date_posted|date:"F d, Y" }}</small>
</div>
<h2>{{ post.title }}</h2>
<p class="article-content">{{ post.content }}</p>
</div>
<div>
<form action="{% url 'like_post' post.id %}">
{% csrf_token %}
{% if is_liked %}
<button type='submit' name='blog_id' value="{{ post.id }}" class="btn btn-danger">Unlike</button>
{% else %}
<button type='submit' name='blog_id' value="{{ post.id }}" class="btn btn-primary">Like</button>
{% endif %}
</form>
</div>
</article>
{% endfor %}
{% endblock %}
you can directly use the redirect shortcut instead of render because render will not going to show all the post. You can either pass all the post in like view or simply call the list view by redirecting it.
from django.shortcuts import redirect
def like_post(request, blog_id):
# rest of code
return redirect(post.get_absolute_url()) # redirect will going to call the BlogsList and your all post will be rendered
When you click like button, your code is rendering from like_post view. In that view, context has no data called blogs. at the end of like_post, you should redirect to your BlogsListView instead of returning a HttpResponse.
you can use a django shortcut function redirect to do this.
from django.shortcuts import redirect
#...
#...
#... your code
def like_post(request, blog_id):
post = get_object_or_404(Blog, id=blog_id)
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return redirect('blog-home')
Also, you need to figure out some way to get is_liked context in home itself. consider checking documentation here

Django - Simple User Register not working [Not saving to DB]

I have simple user registration page, but its not saving to the database.
Issue: Register form displays, upon clicking submit button, doesn't do anything! Stays there (it should show a HttpResponse('User Registered') And save to db
I've know I'm missing something, but what? ideas please.
Views.py
from django.shortcuts import render
from django.views.generic import CreateView
from website.forms import RegisterUserForm
from django.http import HttpResponseForbidden
# Create your views here.
class RegisterUserView(CreateView):
form_class = RegisterUserForm
template_name = "account/register.html"
# Overide dispatch func - check if the user is authenticated or return forbidden
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
return HttpResponseForbidden()
return super(RegisterUserView, self).dispatch(request, *args, **kwargs)
# Overide form valid method behaviour
def form_valid(self, form):
# False commit - don't save to db, locally cleaning users password first
user = form.save(commit=False)
user.set_password(form.cleaned_data['password'])
user.save();
# Change to redirect - later one!
return HttpResponse('User Registered')
def Home(request):
return render(request, 'account/home.html')
Register.html
{% extends 'base.html' %}
{% block title %}
Register
{% endblock %}
{% block head %}
{% load static %}
<link href="{% static 'forms.css' %}" rel="stylesheet">
{% endblock %}
{% block heading %}
<h1>Register</h1>
{% endblock %}
{% block body %}
<div class="bg-contact2" style="background-image: url('images/bg-01.jpg');">
<div class="container-contact2">
<div class="wrap-contact2">
<form class="contact2-form validate-form">
<span class="contact2-form-title">
<h2> Teacher's Register </h2>
</span>
{% csrf_token %}
{{ form.as_p }}
<div class="container-contact2-form-btn">
<div class="wrap-contact2-form-btn">
<div class="contact2-form-bgbtn"></div>
<button class="contact2-form-btn">
Send Your Message
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!--
<h2>FORM</h2>
<form action="{% url 'register' %}" class="contact2-form validate-form" method="post ">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Register">
</form> -->
{% endblock %}
forms.py
from django import forms
from django.contrib.auth.models import User
class RegisterUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput)
class Meta:
# Connect to the user model and select which fields we want input for user model
model = User
fields = ['username', 'email']
# Validate password matched / and clean them
def clean_password2(self):
cd = self.cleaned_data
if cd['password2'] != cd['password']:
raise ValidationError("Password don't match")
return cd['password2']
I think you are missing the type in your button tag:
<form method="POST">
<span class="contact2-form-title">
<h2> Teacher's Register </h2>
</span>
{% csrf_token %}
{{ form.as_p }}
<div class="container-contact2-form-btn">
<div class="wrap-contact2-form-btn">
<div class="contact2-form-bgbtn"></div>
<button type="submit" class="contact2-form-btn">
Send Your Message
</button>
</div>
</div>
</form>
form tag should have an attribute action to tell where to take the data of your form to. So in Register.html you should add
action="{% url 'nameofyourviewgiveninurls.py'%}"
in your form tag

Basic Django form response

I am new to Django and looking to build a quick form with a response.
I am trying to build a form which would ask the user to input his name when the user clicks submit the page should reload and just say "Hello .
urls.py
class Question1Form(forms.Form):
n = forms.CharField(max_length=100,
widget=forms.TextInput(
attrs={'placeholder': 'Number', 'class': 'form-control'}))
views.py
def home(request):
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = [Question1Form.ans()]
return HttpResponse(Question1Form.n)
else:
form = Question1Form()
return render(request, 'index.html', {'form': form})
index.html
<form action="" method="post" class="form">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form-row form">
<div class="col-sm-4">
{{ form.n.errors }}
{{ form.n }}
</div>
<input class="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
So how the code s
You should call instance field, not class field and get value from validated(cleaned) data (see documentation):
return HttpResponse(form.cleaned_data['n'])
If you want to reload the same template with n value:
return render(request, 'index.html', {'form': form, 'n': form.cleaned_data['n']})
and at the template add:
{% if form.is_valid %}
<p> Hello {{ n }} </p>
{% endif %}
if request.method == 'POST':
form = Question1Form(request.POST)
if form.is_valid():
result = form.save()
return render(request, 'index.html', {'created': True})
Then in your HTML you can say
{% if created %}
<p> Hello </p>
{% endif %}
edit I see now you have no action in your form.
So you need to point to that view in your URLS.py.
for example.
from myapp import views as app_views
from django.conf.urls import url
urlpatterns =[
url(r'^my_form/$', app_views.home, name='save_form'),
]
And then add the action to your form.
<form action="{% url 'save_form' %}" method="post" class="form">

django-why this form is always invalid

i have created a form with minimal fields(for testing) , but it never enters form.is_valid()
Here is the minimal code
in the models.py
from django.db import models
class sample(models.Model):
field1=models.CharField(max_length=100)
field2=models.CharField(max_length=100)
in the forms.py
from django.forms import ModelForm
from app.models import sample
class someform(ModelForm):
class Meta:
model=sample
in the views.py
some imports
def index(request):
return render(request, 'app/index.html')
def contact(request):
if request.method=='POST':
form=someform(request.POST)
if form.is_valid():
field1=form.cleaned_data['field1']
field2=form.cleaned_data['field2']
return HttpResponse("valid")
else:
return HttpResponse("invalid")
else:
form=someform()
return HttpResponse("error")
The problem is , it never enters (if form.is_valid()) . Am i missing something ? please help
in the index.html
<html>
<body bgcolor="#2E9AFE">
<form action="contact" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" id="field1" name="field1">
<input type="text" id="field2" name="field2">
<input type="submit" id="submit" name="submit">
</form></body></html>
First pass your form to index.html, when the request is not POST in views.py:
else:
form=someform()
return render(request, 'index.html', locals())
In template you should make it like this:
<form action="contact" method="POST" xmlns="http://www.w3.org/1999/html">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn">Submit</button>
</form>
When receiving the POST query, Django is looking for the 2 fields of IDs id_field1 and id_field2, litteraly, thus your HTML is to be the following:
<html>
<body bgcolor="#2E9AFE">
<form action="contact" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" id="id_field1" name="field1">
<input type="text" id="id_field2" name="field2">
<input type="submit" id="submit" name="submit">
</form>
</body>
</html>
Another solution is to use the {{ form.as_p }} or {{ form.as_table }} to render the inputs inside or tags automatically.
You could also add {{ form.non_field_errors }}, {{ form.field1.errors }}, and {{ form.field2.errors }} in your current HTML to display the form errors when validation fails.

Categories

Resources