I can't add data to the database through form - html

I have been working on making a website in which people can post the evaluation of the restaurant they visited. I want users to post data through a form, but I can't make a form page work as I imagined. To speak the detail, the data put in the form isn't added to the database. Please tell me why the system doesn't work. I can't find the data I typed in the form on admin page and "Tabelog/list.html".
The function named "form" is the one trying to show the form on the page and save data to the database.
models.py
from django.db import models
stars = [
(1,"☆"),
(2,"☆☆"),
(3,"☆☆☆"),
(4,"☆☆☆☆"),
(5,"☆☆☆☆☆")
]
# Create your models here.
class Tabelog(models.Model):
store_name = models.CharField("店名",max_length = 124)
evaluation = models.IntegerField("評価",choices = stars)
comment = models.TextField("口コミ")
def outline(self):
return self.comment[:10]
def __str__(self):
return ("{},{},{}".format(self.store_name,self.evaluation,self.comment[:10]))
forms.py
from django import forms
from django.forms import ModelForm
from Tabelog.models import Tabelog
class CreateTabelogForm(forms.ModelForm):
class Meta:
model = Tabelog
fields = "__all__"
urls.py
from django.urls import path,include
from Tabelog import views
app_name = "Tabelog"
urlpatterns = [
path("lp/", views.lp,name="lp"),
path("list/",views.list,name="list"),
path("detail/<str:store_name>",views.detail,name="detail"),
path("form/",views.form,name="form")
]
views.py
from django.shortcuts import render
from Tabelog.models import Tabelog
from Tabelog.forms import CreateTabelogForm
# Create your views here.
def lp(request):
return render(request,"Tabelog/lp.html")
def list(request):
info = Tabelog.objects.all()
context = {
"info":info,
}
return render(request,"Tabelog/list.html",context)
def detail(request,store_name):
detail = Tabelog.objects.get(store_name = store_name)
context = {
"detail":detail,
}
return render(request,"Tabelog/detail.html",context)
def form(request):
if request.method == "GET":
form = CreateTabelogForm()
context = {
"form":form
}
return render(request,"Tabelog/form.html",context)
else:
form = CreateTabelogForm(request.POST or None)
if request.method == "post" and form.is_valid():
form.save()
return redirect("Tabelog:list")
else:
form = CreateTabelogForm()
context = {
"form":form
}
return render(request,"Tabelog/form.html",context)
base.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<title>Tabelog</title>
</head>
<body>
<div class="container">
<header>
Welcome to Tabelog!
</header>
<main>
{% block content%}
{% endblock %}
</main>
<footer>Thank you for providing information!</footer>
</div>
</body>
</html>
form.html
<!DOCTYPE html>
{% extends 'Tabelog/base.html' %}
{% block content %}
<form action="" method="post">
{{ form.as_p }}
{% csrf_token %}
<button type="submit">SUBMIT!</button>
</form>
{% endblock %}
list.html
<!DOCTYPE html>
{% extends 'Tabelog/base.html' %}
{% block content %}
{% for contents in info%}
<article class="store">
<h1> {{contents.store_name}}</h1>
<h2>{{contents.get_stars_display}}</h2>
<span>{{contents.outline}}</span>
</article>
{% endfor %}
{% endblock %}

I think there is a typo here. You have used request.method=="post", it should request.method == "POST". To be honest, that check is reduandent, so you should remove it.
def form(request):
if request.method == "GET":
form = CreateTabelogForm()
context = {
"form":form
}
return render(request,"Tabelog/form.html",context)
else:
form = CreateTabelogForm(request.POST or None)
if request.method == "post" and form.is_valid():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# remove this code
A refactored version of that code:
def form(request):
form = CreateTabelogForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.save()
return redirect("Tabelog:list")
context = {
"form":form
}
return render(request,"Tabelog/form.html",context)

Related

Connecting a HTML link to an API page

I have a working HTML view and a working detail API RUD view for some simple model objects. Within the HTML view, elements are listed that have their own API RUD view. I'd like to be able to link each list element in the HTML to it's own API RUD view.
Below is my models.py:
class Hints(models.Model):
text = models.TextField(max_length=255)
author = models.CharField(max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.text)
def timestamp_pretty(self):
return self.timestamp.strftime('%b %d %Y')
def get_api_url(self, request=None):
return api_reverse("api-hints1:hints-rud", kwargs={'pk': self.pk}, request=request)
Below is my views.py:
class HTMLAPIView(viewsets.ViewSet):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'base.html'
serializer_class = HTMLSerializer
def list(self, request):
queryset = Hints.objects.order_by('pk')
paginator = Paginator(queryset, 5) # Show 5 items per page
page = request.GET.get('page')
queryset1 = paginator.get_page(page)
return Response({'queryset1': queryset1})
class HintsListApiView(mixins.CreateModelMixin, generics.ListAPIView):
lookup_field = 'pk'
serializer_class = HintsSerializer
def get_queryset(self):
qs = Hints.objects.all()
query = self.request.GET.get("q")
if query is not None:
qs = qs.filter(
Q(text__icontains=query)|
Q(author__icontains=query)
).distinct()
return qs
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def get_serializer_context(self, *args, **kwargs):
return {"request": self.request}
class HintsRudView(generics.RetrieveUpdateDestroyAPIView):
lookup_field = 'pk'
serializer_class = HintsSerializer
def get_queryset(self):
return Hints.objects.all()
def get_serializer_context(self, *args, **kwargs):
return {"request": self.request}
My urls.py:
from .views import HintsRudView, HintsListApiView, HTMLAPIView
from . import views
from django.contrib import admin
from django.conf.urls import url, include
from rest_framework import routers, serializers, viewsets
urlpatterns = [
url(r'^(?P<pk>\d+)$', HintsRudView.as_view(), name='hints-rud'),
url(r'^$', HintsListApiView.as_view(), name='hints-list'),
url(r'^html/', HTMLAPIView.as_view({'get': 'list'}), name='html' )
]
And my relevant HTML code:
As you can see this was my attempt <li>{{ query }}</li>. Unfortunately, I get the following error:
Reverse for 'hints-rud' not found. 'hints-rud' is not a valid view function or pattern name.
{% load staticfiles %}
{% load static %}
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="{% static 'hints1/style.css' %}">
<link href="https://fonts.googleapis.com/css?family=Fjalla+One|Montserrat|Noto+Serif|Nunito|Oswald|Teko" rel="stylesheet">
</head>
<body>
<h1>Handy Dev Hints</h1>
<ul>
{% for query in queryset1 %}
<li>{{ query }}</li>
{% endfor %}
</ul>
<br/>
<br/>
<div class="pagination">
<span class="step-links">
<center>
{% if queryset1.has_previous %}
« First
Previous
{% endif %}
{% if queryset1.has_next %}
Next
Last »
{% endif %}
<br/>
<br/>
<span class="current">
Page {{ queryset1.number }} of {{ queryset1.paginator.num_pages }}
</span>
</center>
</span>
</div>
</body>
</html>
Not sure where to go from here. This doesn't seem like it should be a difficult problem. I've tried removing some $ from the urls.py but it made little difference. I've also tried other views and patterns besides hints-rud but all come back with the same error.
You need to use the namespace, exactly as you do in the get_api_url method.
<a href="{% url 'api-hints1:hints-rud' pk=pk %}">

Django form not showing in template

Why is the form not showing in the browser?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ structure.name }} - Details</title>
</head>
<body>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<h3>Structure: {{ structure }}</h3>
<h3>Ajouter enregistrement</h3>
<form action="{% url 'Structure:addrecord' structure.id %}" method="post">
{% csrf_token %}
{% for structure in all_structures %}
<input type="radio" id="record{{ forloop.counter }}" name="record" value="record.id">
<label for="record{{ forloop.counter }}">
Nom de l'enregistrement: {{ record.record_name }}
</label>
{% endfor %}
</form>
</body>
</html>
When I test this in my browser, and inspect it, it gives me a form of this size: 1340px * 0 px.
I even explicitly gave a style="height: 500px", but it still gives me an empty form.
Here's a screenshot
Thanks for the help guys!
Edit:
Views.py:
from django.shortcuts import render, get_object_or_404
from .models import Structure, Record
def index(request):
all_structures = Structure.objects.all()
return render(request, 'Structures/index.html', {'all_structures': all_structures})
def detail(request, structure_id):
#structure = Structure.objects.get(pk=structure_id)
structure = get_object_or_404(Structure, pk=structure_id)
return render(request, 'Structures/details.html', {'structure': structure})
def addRecord(request, structure_id, record.name, record.type, record.pos, record.long):
r = Record(structure='structure_id', name='record.name', type='record.type', pos='str(record.pos)', long='str(record.long)')
r.save()
return render(request, 'Structures/details.html', {'structure': structure})
Also, I do not quite understand this yet because I am using a video tutorial series by thenewboston's channel, the variables I am using in addRecord are not known, and I want to use them from the model. Here are the models and urls files as well:
models.py:
from django.db import models
class Structure(models.Model):
name = models.CharField(max_length=120)
path = models.CharField(max_length=200)
def __str__(self):
return self.name
class Type(models.Model):
typename = models.CharField(max_length=50)
def __str__(self):
return self.typename
class Record(models.Model):
structure = models.ForeignKey(Structure, on_delete=models.CASCADE) #each structure has many records, each per line
name = models.CharField(max_length=200)
type = models.ForeignKey(Type)
pos = models.IntegerField()
long = models.IntegerField()
def __str__(self):
return self.name
urls.py:
from django.conf.urls import url
from . import views
app_name = 'Structure'
urlpatterns = [
# /structures/
url(r'^$', views.index, name='index'),
# /structures/id
url(r'^(?P<structure_id>[0-9]+)/$', views.detail, name='detail'),
# /structures/addrecord
url(r'^(?P<structure_id>[0-9]+)/addrecord/$', views.addRecord, name='addrecord'),
]
Look for the value of all_structures that you are passing in context from views.
If it is empty or not passed, form fields won't be displayed as per your template code.
Try to print its value either in the console or in template. That's how to Debug.
Hope this helps.

How to display the edited profile picture in django

I am able to upload the profile picture but i am not able edit it
I have the form populating with the image browse option, but when I click save, it doesn't actually update in template. but it is working fine in admin
views.py
def create_form(request):
form = AlbumForm(request.POST or None, request.FILES or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.image= request.FILES['image']
album.save()
return render(request, 'about.html', {'album': album})
context = {
"form": form,
}
return render(request, 'create_form.html', context)
def profile_edit(request):
if request.method == 'POST':
form = AlbumForm(request.POST, instance=request.user.album)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
form.save()
return redirect(reverse('about'))
else:
form = AlbumForm(instance=request.user.album)
args = {'form': form}
return render(request, 'profile_edit.html', args)
models.py
class Album(models.Model):
user = models.OneToOneField(User)
image = models.FileField()
forms.py
class AlbumForm(forms.ModelForm):
class Meta:
model = Album
fields = ['image']
profile_edit.html
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'profile_edit' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">save</button>
</form>
<div>
<img src="{{ user.album.image.url }}" class="img-responsive">
</div>
{% endblock %}
Try this
AlbumForm(request.POST, request.FILES, instance=request.user.album)
You need to add request.FILES to your AlbumForm in the profile edit view.
If you upload file you must use request.Files
read for more info this link
https://docs.djangoproject.com/en/1.10/topics/http/file-uploads/#basic-file-uploads

Form not Rendered in Django

I am trying to display a form in Django HTML Template, but it is not being Rendered
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Description, Bill
from django.http import Http404
from .forms import DForm
from .forms import BForm
import pprint
# Create your views here.
def index(request):
context = {}
return render(request, 'front/index.html', context)
def commitbill(request):
if request.method == "POST":
form = BForm(request.POST,request.FILES)
if form.is_valid():
print form.errors
Bill = form.save()
return HttpResponse(str(Bill.bill_id()))
print form.errors
return HttpResponse("fail")
forms.py
from django import forms
from .models import Description, Bill
class BForm(forms.ModelForm):
class Meta:
db_table = 'inventory_bill'
model = Bill
fields = ('party', 'inovice', 'amount','image','image_caption')
the template, portion of which is not being Rendered!
{% load staticfiles %}
<html>
<head>
<title></title>
<link href="{%static "./styles/bootstrap.min.css" %}" rel="stylesheet" />
</head>
<body>
<h1 style="text-align: center;">Rahul's Shop</h1>
<h2 style="text-align: center;">Inventory</h2>
<form id="bill" action ="{% url 'front:commitbill' %}" method = "post" class="form-horizontal" enctype="multipart/form-data">
{% csrf token %}
{{ form.as_p }}
<div class="container">
<div class="row">
<input type="button" id="add_items" class="col-md-offset-5 col-md-2 btn btn-success" value="Add items" \>
</div>
</div>
</form>
The portion {{ form.as_p }} is not being Rendered, That's my main Issue!
your index should read like this, you need to pass the form to the template context.
def index(request):
form = BForm()
context = {
'form': form,
}
return render(request, 'front/index.html', context)

Django for loop issue

I think this is something simple but I cannot find the error at all.
The code inside the for loop is not executing. When I look up the database and the admin site the content displays fine but trying to display on the HTML is not working:
Views
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now())
return render(request, "blog/bloglist.html", {'posts': posts})
Urls:
from django.conf.urls import url
import views
urlpatterns = [
url(r'^blog/$', views.post_list),
]
Base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog</title>
</head>
<body>
<h1>Base</h1>
{% block content %}
{% endblock %}
</body>
</html>
bloglist.html
{% extends "base.html" %}
{% block content %}
<h1>Blog </h1>
{% for post in posts %}
<h3>{{ post.title }}</h3>
{% endfor %}
{% endblock %}
and just to be sure the model is included as well
Models:
from django.db import models
from django.utils import timezone
# Create your models here.
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
content = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
I know its pretty simple but I just cannot find the error. Thanks in advance