Where am I going wrong - python

So I am very new to Django and I am confused where am I going wrong. I am trying to create a simple calculator to calculate profit estimates. Here is what it shows in my HTML so far. Kind of confused where am I going wrong. Any help appreciated.
This the HTML file code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
{% block content %}
<form action = "something" method = "post">
{% csrf_token %}
{{ form }}
<input type="submit" value=Submit>
</form>
{% endblock %}
</body>
</html>
This is forms.py
from django import forms
from .models import Calc
class Calculator(forms.ModelForm):
class Meta:
model = Calc
fields = ['gross_receivable', 'TDS', 'bank_charges', 'vendor_payable']
This is the models.py
from django.db import models
# Create your models here.
class Calc(models.Model):
gross_receivable = models.IntegerField()
TDS = models.BooleanField(default=False)
bank_charges = models.BooleanField(default=False)
vendor_payable = models.IntegerField()
This is the views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import Calc
def something(request):
form = Calc()
context = {'form': form}
return render(request, "calculator1.html", context)

Your form name is Calculator but you are importing your model as form.
You should change
from .forms import Calc
to
from .forms import Calculator
and in the something function
form = Calculator()

Related

Django 3: is_valid() is always false using FileField and FloatField

I am trying to make a simple form in Django that accepts some file upload fields and a few float fields. However, when I run this in my browser, the is_valid() never gets triggered even when all forms are filled in. I have looked through the Django docs and have tried to recreate the examples as much as possible, but I can't figure out what is wrong. I know that the is_valid() is not true because the page does not redirect to another page when submit is pressed. Also, if I go into the admin page, no instances of MyModel are made.
Here is my code.
models.py:
from django.db import models
# Create your models here.
class MyModel(models.Model):
file1 = models.FileField()
file2 = models.FileField()
x = models.FloatField()
y = models.FloatField()
z = models.FloatField()
def __str__(self):
return self.file1
forms.py:
from django import forms
from django.forms import ModelForm
from .models import MyModel
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = '__all__'
views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from .forms import MyForm
# Create your views here.
def index_view(request):
if request.method == 'POST':
form = MyForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('some_page')
else:
form = DocumentsForm()
return render(request, 'index.html', {'form':form})
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Home Page!</h1>
<form method="POST" action="/">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Submit">
</form>
</body>
</html>
My guess is it has to do with the fact that you haven't included enctype="multipart/form-data" in your <form> declaration in the HTML. It should look like this:
<form action="/" method="post" enctype="multipart/form-data" class="">
The multipart/form-data is necessary when uploading a file through forms.
Since you are sending both data and files, you need to specify the encoding of the form to:
<form enctype="multipart/form-data" method="POST" action="/">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Submit">
</form>

Form preview in Django

I am building a registration form. Whenever a user fills the form and clicks the register button I want them to see the preview of their submissions. I am having problems with the arguments. Here goes my code:
models.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
# Create your models here.
class Register(models.Model):
regChoice = (
('Self', 'Self'),
('Group', 'Group'),
('Corporate', 'Corporate'),
('Others', 'Others'),
)
name = models.CharField(max_length=50)
email = models.EmailField(max_length=254,null=True)
phoneNumber = PhoneNumberField(null=True)
idCard = models.ImageField(null=True)
regType = models.CharField(max_length=25, choices=regChoice,null=True)
ticketNo = models.IntegerField(default=1)
def __str__(self):
return self.name
forms.py
from django import forms
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import *
class RegisterForm(ModelForm):
name = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your full name...'}))
email = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your email...'}))
phoneNumber = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'Your phone number...'}))
class Meta:
model = Register
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='home'),
path('preview.html/<str:pk>', views.preview, name="preview")
]
views.py
from django.shortcuts import render, redirect
from .models import *
from .forms import *
# Create your views here.
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'event/index.html', context)
def preview(request, pk):
reg = Register.objects.get(id=pk)
prev = RegisterForm(instance=reg)
if request.method == 'POST':
form = RegisterForm(request.POST, instance=reg)
if form.is_valid():
form.save()
return redirect('/')
context = {'reg':reg, 'prev':prev}
return render(request, 'event/preview.html', context)
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Registration</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/script.js' %}"></script>
</head>
<body>
<div class="mobile-screen">
<div class="header">
</div>
<div class="logo"></div>
<form id="login-form" method="POST" action="{% url 'preview' form.id %}" enctype="multipart/form-data">
{% csrf_token %}
{{form.name}}
{{form.email}}
{{form.phoneNumber}}
<legend style="color: aliceblue;">Upload ID card: </legend>{{form.idCard}}
<div style="text-align: center; color: aliceblue;">Registration Type: {{form.regType}}</div>
{{form.ticketNo}}
<input class="btn btn-sm btn-primary" type="submit" value="Register" name="Register">
</form>
</div>
</body>
</html>
preview.html
Hello {{prev.name}},
your email is {{prev.email}}
your phone number is {{prev.phoneNumber}}
your idCard photo is {{prev.idCard.url}}
your registration type is {{prev.regType}}
your number of tickets is {{prev.ticketNo}}
The error I am having is:
NoReverseMatch at /
Reverse for 'preview' with arguments '('',)' not found. 1 pattern(s) tried: ['preview\.html/(?P[^/]+)$']
When someone reaches your index page and enters the form we need to
Submit the form as a POST request to index view
Save the form thereby creating a model in the DB
Redirect the user to preview view using the above id
To do that the code needs to be somewhat like this, I have not tested it, but you should get the idea.
from django.shortcuts import redirect
def index(request):
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save()
return redirect('preview', pk=instance.id)
context = {'form':form}
return render(request, 'event/index.html', context)
Inside your index.html change
action="{% url 'preview' form.id %}"
to
action=""
as we want it to post to the INDEX view as that is where out POST handling logic is.
The index view then redirects to preview using the newly generated object.
Also as mentioned by #Snir in the other answer, having .html in URLS is not a standard practice. It would be better to simple make it something like:
path('preview/<str:pk>', views.preview, name="preview")
The URL patterns are regexes, so you'll have to escape special regex characters, like the dot. Try (add r) or remove the dot:
path(r'preview.html/<str:pk>', views.preview,
name="preview")

Django_tables2 with delete buttom

How is going? I'm learning to programming in django. For the moment I'm building a simple app that utilizing a form update the referenced table.
Now I'm try to add a delete button in each row of my table but, beside I have tried a lot of solutions, I didn't find one that works correctly.
Below my code:
urls
from django.urls import path
from app import views
app_name = 'main'
urlpatterns = [
path('', views.homepage, name='homepage'),
path('delete_item/<int:pk>', views.delete_item, name="delete_item"),
]
forms
from django import forms
from .models import Income
class IncomeModelForm(forms.ModelForm):
class Meta:
model = Income
fields = "__all__"
tables
import django_tables2 as tables
from django_tables2.utils import A
from .models import Income
class PersonTable(tables.Table):
delete = tables.LinkColumn('main:delete_item', args=[A('delete-id')], attrs={'a': {'class': 'btn'}})
class Meta:
model = Income
template_name = "django_tables2/bootstrap.html"
views
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import ListView
from .models import Income
from .tables import PersonTable
from .forms import IncomeModelForm
def homepage(request):
table = PersonTable(Income.objects.all())
if request.method == 'POST':
form = IncomeModelForm(request.POST)
if form.is_valid():
print("Il form รจ valido")
new_input = form.save()
else :
form = IncomeModelForm()
context= {"form": form,
"table":table }
return render(request, "app/base.html", context)
def delete_item(request, pk):
Income.objects.filter(id=pk).delete()
items = Income.objects.all()
context = {
'items': items
}
return render(request, 'app/base.html', context)
html
{% load static %}
{% load render_table from django_tables2 %}
<!doctype html>
<html lang="it">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello, world!</title>
</head>
<div class="container">
<form class="" action="" method="post">
{% csrf_token %}
{{form|crispy}}
<input type="submit" class="btn btn-danger" value="INVIA">
</form>
</div>
<br>
<br>
<div class="container">
{% render_table table %}
</form>
</div>
</body>
</html>
My table disply the column "Delete" but no buttoms, only a "-". Why? Where is my error?
Please add this
text='static text', argument like delete = tables.LinkColumn('main:delete_item',text='Delete', args=[A('delete-id')], attrs={'a': {'class': 'btn'}})
.
Hope it will work

How do I get the values from input text fields from my custom form through the request: Django 3.0?

So, I've been trying hard, getting values from input fields in my custom form.
I have a url that corresponds to the form and that form redirects it to the same form again.
The view of the form url checks whether the request method is Post. If it is, then I declare a variable equal to request.POST, I then assigned those values to my model- item_description(). Here is the code of the views.py:
def addItem(request):
if request.method == "POST":
data = request.POST
print(data.__dict__)
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
else:
HttpResponse("Something went wrong!")
return render(request, 'ims/addItemForm.html')
HTML form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IMS| Add Item</title>
</head>
<body>
<form action="{% url 'Item-addition' %}" method="post">
{% csrf_token %}
<input type="text" name="item_name" placeholder="Enter Item Name">
<input type="text" name="item_number" placeholder="Enter Item Number">
<input type="text" name="item_quantity" placeholder="Enter Item Quantity">
<button type="submit" name="add" value="add">Add Item</button>
</form>
See items
</body>
</html>
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('add_item', views.addItem, name='Item-addition'),
path('items', views.itemsList, name='Items-list'),
]
models.py:
from django.db import models
class item_description(models.Model):
item_name = models.CharField(max_length=200)
item_number = models.CharField(max_length=200)
item_quantity = models.CharField(max_length=200)
def __str__(self):
return self.item_name
Also, I printed out the request which is a dictionary, but it was not having any of the values. Here is the printed request dictionary: {'_encoding': 'utf-8', '_mutable': False}.
Here is the error which I am getting:
File "/home/zaid/inventoryManagement/venv/src/ims/views.py", line 13, in addItem
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
AttributeError: 'QueryDict' object has no attribute 'item_name'
Please help me getting values from the input fields.
Your mistakes:
item_description(item_name=data.item_name, item_number=data.item_number, item_quantity=data.item_quantity)
data is a QueryDict, so you must access the data in it using data['item_name'] or data.get('item_name') as you would for a regular dict.
item_description(...) doesn't actually do anything. It does not save anything to the database. To save to the database, you must use item_description.objects.create(...).
Other problems with your code:
you render the form fields on your own
you extract the POST data on your own
you attempt to save to the database on your own
you are missing input validation (what if some required values are missing? e.g. what if item_name is not submitted?)
you did not provide a suitable error message as feedback to the user if he/she enters inappropriate values (e.g. a string of length 201).
Django's ModelForm is able to handle all of these issues, so please use ModelForm instead.
If models.py is this:
from django.db import models
class ItemDescription(models.Model):
item_name = models.CharField(max_length=200)
item_number = models.CharField(max_length=200)
item_quantity = models.CharField(max_length=200)
def __str__(self):
return self.item_name
Then, create a ModelForm in forms.py:
from django import forms
from .models import ItemDescription
class ItemDescriptioneForm(forms.ModelForm):
class Meta:
model = ItemDescription
fields = ['item_name', 'item_number', 'item_quantity']
In your views.py, use the ModelForm you just created:
from django.shortcuts import render, redirect
from .forms import ItemDescriptionForm
def addItem(request):
if request.method == 'POST':
form = ItemDescriptionForm(request.POST)
if form.is_valid():
form.save()
return redirect('Items-list')
else:
form = ItemDescriptionForm()
return render(request, 'ims/addItemForm.html', {
'form': form,
})
Show the form in your template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Add Item</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
</body>
</html>

CSRF token missing or incorrect in Django form

I am very new to Django forms. I am trying to simply get a value from a text field and store it in a database. I am getting an error report saying:
*Forbidden (403)
CSRF verification failed.
Request aborted.
Reason given for failure:
CSRF token missing or incorrect.
For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.*
Where am I going wrong?
My views.py code is:
from django.shortcuts import render
from feedback.models import Test
from mysite.forms import TestForm
from django.http import HttpResponse
from django.template import Context, loader
def test_view(request):
form = TestForm
t = loader.get_template('form.html')
c = RequestContext(request,{'n':''})
if request.method=='POST':
form = TestForm(request.POST)
if form.is_valid():
in_name = request.POST.get("firstname")
fd = Test(name = in_name)
fd.save()
return HttpResponse(t.render(c))
My models.py code is:
from django.db import models
from django.forms import ModelForm
class Test(models.Model):
name = models.CharField(max_length=255)
class TestForm(ModelForm):
class Meta:
model = Test
fields = ['name']
My forms.py code is:
from django import forms
class TestForm(forms.Form):
name = forms.CharField()
My HTML template is:
<!DOCTYPE html>
<html>
<head>
<title>test form</title>
</head>
<body>
<form method = "POST">
{% csrf_token %}
First name:<br>
<input type="text" name="firstname" value = {{ n }}>
<br><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
You do it in a wrong, very PHPish, way.
Move the form definition from models.py to the forms.py, so your feedback/forms.py should be:
from django.forms import ModelForm
class TestForm(forms.ModelForm):
class Meta:
model = Test
fields = ['name']
The feedback/views.py should be simplified to:
from django.shortcuts import render, redirect
from feedback.forms import TestForm
def test_view(request):
if request.method == 'POST':
form = TestForm(request.POST)
if form.is_valid():
form.save()
return redirect('.')
else:
form = TestForm()
return render(request, 'form.html', {'form': form})
And the template:
<!DOCTYPE html>
<html>
<head>
<title>test form</title>
</head>
<body>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
</body>
</html>

Categories

Resources