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
Related
I'm fairly new to using the django framework and recently I made a system with it where it submits data to mysql db through a html form. I got it working eventually and everything seemed quite fine, though I noticed a bug where if I refresh the page django stops sending data to mysql, has this ever happened to anyone?
Stuff for reference:
views.py
from django.shortcuts import render
from websiteDB.models import dbInsert
from django.contrib import messages
def insertToDB(request):
if request.method == "POST":
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert()
post.uname = request.POST.get('uname')
post.email = request.POST.get('email')
post.message = request.POST.get('message')
post.save()
messages.success(request, "Message sent successfully.")
return render(request, "contact.html")
else:
return render(request, "contact.html")
models.py
from django.db import models
class dbInsert(models.Model):
uname = models.CharField(max_length=100)
email = models.EmailField()
message = models.TextField()
class Meta:
db_table = "contactrequest"
urls.py
"""
websiteDB URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
from . import views
from . import index
urlpatterns = [
#path('admin/', admin.site.urls),
path('homepage', index.page_home, name= 'hpage'),
path('', views.insertToDB),
path('contactpage', index.contact_page, name= 'cpage')
]
contact.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght#200&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/css/styles.css' %}">
<title>Document</title>
</head>
<body style="background-color: rgb(74, 36, 110);">
<script src="{% static 'js/main.js' %}"></script>
<div class="top-nav">
HOME
PRODUCTS
CONTACT
ABOUT
COMMUNITY
</div>
<div class="div-align">
<h2>Contact</h2>
<p>Reach us for questions/concerns through the form below.</p>
</div>
<form class="fontmaker" method="post">
{% csrf_token %}
<label for="Username">Username:</label><br>
<input type="text" id="Username" name="uname" required><br>
<label for="E-mail">E-mail:</label><br>
<input type="text" id="Email" name="email" required>
<label for="Reason" class="margin">Message:</label>
<textarea id="Reason" name="message" rows="10" cols="60" required>Type your reason of contact here.</textarea>
<input type="submit" value="Submit" class="rounded-corners" id="submitBtn">
{% if messages %}
{% for message in messages %}
{{message}}
{% endfor %}
{% endif %}
</form>
</body>
</html>
There are no errors in terminal, and the button click also properly sends a POST req:
Terminal output
I'm also new to posting on stackoverflow, tell me if there's something else to improve on in the future when posting.
index.py
from django.http import HttpResponse
from django.shortcuts import render
def page_home(request):
return render(request, 'index.html')
def contact_page(request):
return render(request, 'contact.html')
Thanks in advance.
If you render the contactpage/ URL, then if you submit the form, you will submit it to the contact view, but that view does not handle the data, nor does it create any entry. You must make sure that you post the form to the insertToDB view. You can do this by giving the view a name:
urlpatterns = [
# …,
path('', views.insertToDB, name='insertToDB'),
# …
]
and then specify the endpoint in the form:
<form class="fontmaker" method="post" action="{% insertToDB %}">
<!-- … -->
</form>
In case of a successful POST request, you should also redirect, for example with:
from django.shortcuts import redirect
def insertToDB(request):
if request.method == 'POST':
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert.objects.create(
uname = request.POST['uname'],
email = request.POST['email'],
message = request.POST['message']
)
messages.success(request, 'Message sent successfully.')
return redirect('cpage')
return render(request, 'contact.html')
else:
return render(request, 'contact.html')
I would advise to work with Django forms [Django-doc], for example a modelform [Django-doc] to validate and clean form input and remove a lot of boilerplate code.
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")
I am building a registration form. I want the users to review their filled-up forms to confirm their submissions. But in my code the form is submitted twice (overwritten not duplicated). Once when they hit the submit button after filling their form and overwritten after hitting the submit button on the review page. As a result if they close the browser in the review page their page is still submitted, which I don't want to allow.
views.py
from django.shortcuts import render, redirect
from .models import *
from .forms import *
# Create your views here.
def index(request):
form = RegisterForm()
print('hi')
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
z = form.cleaned_data
if (Register.objects.filter(email=z['email']).exists()):
print('already exist')
return redirect('/')
else:
print('xx')
return redirect('preview', pk=z.get('id'))
context = {'form':form}
return render(request, 'event/index.html', context)
def preview(request, pk):
prev = Register.objects.get(id=pk)
if request.method == 'POST':
prev.save()
print('overwrite')
return redirect('/')
print('yy')
context = { 'prev':prev,'id':pk}
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="" enctype="multipart/form-data">
{% csrf_token %}
{{form.name}}
{{form.email}}
<input class="btn btn-sm btn-primary" type="submit" value="Register" name="Register">
</form>
</div>
</body>
</html>
models.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
# Create your models here.
class Register(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField(max_length=254,null=True)
def __str__(self):
return self.name
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()
I am trying to configure HTML formto work with Django Models rather than using built-in Forms in the framework. I have made the form using Html below and have pasted the code for Model, View and Urls.py. The problem is when I click the submit button, it doesn't perform any action. I am able to view the form but it doesn't serves the purpose. I know the question is very lame, but how would configure the HTML to work with the django model so that the data can be saved to the database?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body style="font-family:Courier New">
<h1>Add / Edit Book</h1>
<hr/>
<form id="formHook" action="/istreetapp/addbook" method="post">
<p style="font-family:Courier New">Name <input type="text" placeholder="Name of the book"></input></p>
<p style="font-family:Courier New">Author <input type="text" placeholder="Author of the book"></input></p>
<p style="font-family:Courier New"> Status
<select>
<option value="Read">Read</option>
<option value="Unread">Unread</option>
</select>
</p>
<input type="submit" id="booksubmit" value="Submit"></input>
</form>
</body>
</html>
View
from django.shortcuts import HttpResponse
from istreetapp.models import bookInfo
from django.template import Context, loader
from django.shortcuts import render_to_response
def index(request):
booklist = bookInfo.objects.all().order_by('Author')[:10]
temp = loader.get_template('app/index.html')
contxt = Context({
'booklist' : booklist,
})
return HttpResponse(temp.render(contxt))
Model
from django.db import models
class bookInfo(models.Model):
Name = models.CharField(max_length=100)
Author = models.CharField(max_length=100)
Status = models.IntegerField(default=0) # status is 1 if book has been read
def addbook(request, Name, Author):
book = bookInfo(Name = Name, Author=Author)
book.save
return render(request, 'templates/index.html', {'Name': Name, 'Author': Author})
Urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('app.views',
url(r'^$', 'index'),
url(r'^addbook/$', 'addbook'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
You forgot to define name in each of your input
<form id="formHook" action="/addbook/" method="post">
{% csrf_token %}
<p style="font-family:Courier New">
Name <input type="text" name="name" placeholder="Name of the book"></input>
</p>
<p style="font-family:Courier New">
Author <input type="text" name="author" placeholder="Author of the book"></input>
</p>
<p style="font-family:Courier New">
Status
<select name="status">
<option value="Read">Read</option>
<option value="Unread">Unread</option>
</select>
</p>
<input type="submit" id="booksubmit" value="Submit"></input>
</form>
Your addbook must be in the views.py not in your models.py.
You don't have to define templates/index.html in your render, it is understood in your settings
def addbook(request):
if request.method == 'POST':
name = request.POST['name']
author = request.POST['author']
bookInfo.objects.create(Name = name, Author=author)
return render(request, 'index.html', {'Name': name, 'Author': author})
main urlconf
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'project_name.views.index'),
url(r'^addbook/$', 'project_name.views.addbook'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
You need to add name attributes to your html form then process the form submission in the view. Something like -
from django.http import HttpResponseRedirect
from django.shortcuts import render
def book_view(request):
if request.method == 'POST':
name = request.POST['name']
author = request.POST['author']
book = BookInfo(name=name, author=author)
if book.is_valid():
book.save()
return HttpResponseRedirect('your_redirect_url')
else:
return render(request, 'your_form_page.html')
Have a look at the docs on the request.POST dictionary.
However you really would be better off doing this with a django ModelForm -
class BookForm(ModelForm):
class Meta:
model = BookInfo # I know you've called it bookInfo, but it should be BookInfo
then in your view -
from django.http import HttpResponseRedirect
from django.shortcuts import render
def book_view(request, pk=None):
if pk:
book = get_object_or_404(BookInfo, pk=pk)
else:
book = BookInfo()
if request.method == 'POST':
form = BookForm(request.POST, instance=book)
if form.is_valid():
book = form.save()
return HttpResponseRedirect('thanks_page')
else:
form = BookForm(instance=book)
return render(request, 'your_form_page.html', {'form': form)
And your_form_page.html can be as simple as -
<form action="{% url book_view %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Have a look at the docs on working with forms.