I am working on a Django project and I want to fill out a form and save the data in the db database and then be able to show it on another page, I managed to create the form, following some tutorials, but it does not write me anything in the database. Here's how I currently have things:
forms.py
from django import forms
from .models import AusenciasForm
from django.contrib.auth.models import User
class AusenciasForm(forms.ModelForm):
class Meta:
model = AusenciasFormulario
fields = '__all__'
widgets = {'fecha': forms.DateInput(attrs={'type': 'date'})}
models.py
from django.db import models
from django.utils import timezone
import datetime
from django.contrib.auth.models import User
from django.urls import reverse
class AusenciasFormulario(models.Model):
#razon = models.ModelChoiceField(label="Razón", queryset=razones.object.all())
fecha = models.DateField(("Date"),default=datetime.date.today)#label="Fecha", required=True
razon = [
('Estudios/Examen','Estudios/Examen'),
('Enfermedad','Enfermedad'),
('Lesión','Lesión'),
('Motivos personales','Motivos personales'),
('Motivos familiares','Motivos familiares'),
('Otros','Otros')
]
motivo = models.CharField(max_length=100, choices=razon, default='Otros')
comentarios= models.CharField(max_length=200,blank=True)
jugador = User
views.py
class FormularioAusenciaView(HttpRequest):
def index(request):
ausencias_formulario = AuForm.objects.all()
return render(request, 'blog/ausencias.html', {'ausencias_formulario':ausencias_formulario})
def procesar_formulario(request):
#if request.method == 'POST':
form = AusenciasForm(request.POST)
if form.is_valid():
form.save()
form = AusenciasForm()
return HttpResponseRedirect('ausencias/') #Add your route name, where you want to go after form save
else:
form = AusenciasForm()
return render(request, 'blog/formularioAusencia.html', {'form':form})
Urls.py
from django.urls import path
from .views import PostListView, PostDetailView, PostCreateView, PostUpdateView, PostDeleteView,UserPostListView, FormularioAusenciaView, ausencias
from .import views
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('', login_required(PostListView.as_view()), name='blog-home'),
path('user/<str:username>',login_required( UserPostListView.as_view()), name='user-posts'),
path('post/<int:pk>/',login_required( PostDetailView.as_view()), name='post-detail'),
path('post/new/',login_required( PostCreateView.as_view()), name='post-create'),
path('post/<int:pk>/update/',login_required( PostUpdateView.as_view()), name='post-update'),
path('post/<int:pk>/delete/',login_required( PostDeleteView.as_view()), name='post-delete'),
path('about/', views.about, name='blog-about'),
path('formularioAusencia/',login_required( FormularioAusenciaView.index), name='formularioAusencia'),
#path('asistencia_done/',formularioAusencia, name='asistencia_done'),
path('ausencias/',login_required( views.ausencias), name='ausencias'),
]
the template
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
{% if user.is_authenticated %}
<p></p><a class="mr-2">Rellenar si no vas a poder acudir a un próximo entrenamiento o partido</a></p>
<!--<label><input type="checkbox" id="cbox1" value="first_checkbox"></label><br>-->
<form method="POST" action="{% url 'ausencias' %}">{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-danger btn-sm mt-1 mb-1" type="submit">Enviar</button>
</form>
</div>
<div class="form-group">
</div>
{% endif %}
</div>
{% endblock content %}
In forms.py:
You have imported wrong model name:
change this
from .models import AusenciasForm
To this:
from .models import AusenciasFormulario
And in views.py file:
You have not added any orm query so that's why it is not saving in db.
views.py :
Do this:
def index(request):
ausencias_formulario = AusenciasFormulario.objects.all() #Here i have retrieved data using orm
return render(request, 'blog/formularioAusencia.html', {'ausencias_formulario':ausencias_formulario})
def procesar_formulario(request):
if request.method == 'POST':
form = AusenciasForm()
if form.is_valid():
form.save()
return HttpResponseRedirect('/home/') #Add your route name, where you want to go after form save
else:
form = AusenciasForm()
return render(request, 'blog/formularioAusencia.html', {'form':form})
And in your templates:
formularioAusencia.html
<form method='post'>
{{form}}
<input type="submit" /> #Added new code here
</form>
After submitting above form, using below code, you will get that fields.
Add below code after the form tag.
To display all the fields to templates add the below code in template:
{% for field in ausencias_formulario %}
{{field.fecha}}
#Add remaining fields here to display
{% endfor %}
Related
I am trying to make a contact form, but I guess I'm doing it wrong.
When I access /contact and put name, email, content in each field and click a submit button, I got an error.
NoReverseMatch at /contact/ Reverse for 'contact_result' not found.
'contact_result' is not a valid view function or pattern name.
view.py
from django.urls import reverse_lazy
from django.views.generic import TemplateView
from django.views.generic.edit import FormView
from .forms import ContactForm
class ContactFormView(FormView):
template_name = 'contact/contact_form.html'
form_class = ContactForm
success_url = reverse_lazy('contact_result')
def form_valid(self, form):
form.send_email()
return super().form_valid(form)
class ContactResultView(TemplateView):
template_name = 'contact/contact_result.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['success'] = "completed"
return context
urls.py
from . import views
from .views import DbDetail,ContactFormView, ContactResultView
app_name = 'db'
urlpatterns = [
path('', views.DbList.as_view(), name='list'),
path('contact/', ContactFormView.as_view(), name='contact_form'),
path('contact/result/', ContactResultView.as_view(), name='contact_result'),
]
contact_form.html
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-8">
<h1>inquily</h1>
<p>inquily form</p>
<form method="POST">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">submit</button>
</form>
</div>
</div>
</div>
{% endblock %}
contact_result.html
{% block content %}
{{ success }}
{% endblock %}
I just mentioned the above settings in this question but still if more code is required then tell me I'll update my question with that information.
I am following the tutorial on [Protecting Views][1] and I have trouble understanding the tutorial. When I click the the Reply Button, it does not take me to the link to reply to the topic, and displayed a # in the URL instead. I had to type in the URL to get to that point. And when I posted something, it didn't redirect, and the new topic that I replied to wasn't there. I don't know why this is happening.
Here's my forms.py file
from django import forms
from .models import Topic, Post
class NewTopicForm(forms.ModelForm):
message = forms.CharField(
widget=forms.Textarea(),
max_length=4000,
help_text='The max length of this field is 4000.'
)
class Meta:
model = Topic
fields = ['subject', 'message']
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['message', ]
and here's my urls.py file
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth import views as auth_views
from accounts import views as accounts_views
from boards import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^signup/$', accounts_views.signup, name='signup'),
url(r'^login/$', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
url(r'^logout/$', auth_views.LogoutView.as_view(), name='logout'),
url(r'^reset/$',
auth_views.PasswordResetView.as_view(
template_name='password_reset.html',
email_template_name='password_reset_email.html',
subject_template_name='password_reset_subject.txt'
),
name='password_reset'),
url(r'^reset/done/$',
auth_views.PasswordResetDoneView.as_view(template_name='password_reset_done.html'),
name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
auth_views.PasswordResetConfirmView.as_view(template_name='password_reset_confirm.html'),
name='password_reset_confirm'),
url(r'^reset/complete/$',
auth_views.PasswordResetCompleteView.as_view(template_name='password_reset_complete.html'),
name='password_reset_complete'),
url(r'^settings/password/$', auth_views.PasswordChangeView.as_view(template_name='password_change.html'),
name='password_change'),
url(r'^settings/password/done/$', auth_views.PasswordChangeDoneView.as_view(template_name='password_change_done.html'),
name='password_change_done'),
url(r'^boards/(?P<pk>\d+)/$', views.board_topics, name='board_topics'),
url(r'^boards/(?P<pk>\d+)/new/$', views.new_topic, name='new_topic'),
url(r'^boards/(?P<pk>\d+)/topics/(?P<topic_pk>\d+)/$', views.topic_posts, name='topic_posts'),
url(r'^boards/(?P<pk>\d+)/topics/(?P<topic_pk>\d+)/reply/$', views.reply_topic, name='reply_topic'),
url(r'^admin/', admin.site.urls),
]
And here is my views.py file
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect, render
from .forms import NewTopicForm, PostForm
from .models import Board, Post, Topic
def home(request):
boards = Board.objects.all()
return render(request, 'home.html', {'boards': boards})
def board_topics(request, pk):
board = get_object_or_404(Board, pk=pk)
return render(request, 'topics.html', {'board': board})
#login_required
def new_topic(request, pk):
board = get_object_or_404(Board, pk=pk)
if request.method == 'POST':
form = NewTopicForm(request.POST)
if form.is_valid():
topic = form.save(commit=False)
topic.board = board
topic.starter = request.user
topic.save()
Post.objects.create(
message=form.cleaned_data.get('message'),
topic=topic,
created_by=request.user
)
return redirect('topic_posts', pk=pk, topic_pk=topic.pk)
else:
form = NewTopicForm()
return render(request, 'new_topic.html', {'board': board, 'form': form})
def topic_posts(request, pk, topic_pk):
topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
return render(request, 'topic_posts.html', {'topic': topic})
#login_required
def reply_topic(request, pk, topic_pk):
topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.topic = topic
post.created_by = request.user
post.save()
return redirect('topic_posts', pk=pk, topic_pk=topic_pk)
else:
form = PostForm()
return render(request, 'reply_topic.html', {'topic': topic, 'form': form})
and here's my templates/reply_topic file
{% extends 'base.html' %}
{% load static %}
{% block title %}Post a reply{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item">{{ topic.board.name }}</li>
<li class="breadcrumb-item">{{ topic.subject }}</li>
<li class="breadcrumb-item active">Post a reply</li>
{% endblock %}
{% block content %}
<form method="post" class="mb-4" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-success">Post a reply</button>
</form>
{% for post in topic.posts.all %}
<div class="card mb-2">
<div class="card-body p-3">
<div class="row mb-3">
<div class="col-6">
<strong class="text-muted">{{ post.created_by.username }}</strong>
</div>
<div class="col-6 text-right">
<small class="text-muted">{{ post.created_at }}</small>
</div>
</div>
{{ post.message }}
</div>
</div>
{% endfor %}
{% endblock %}
I followed the tutorial exactly, but the reply worked when I typed in the URL, not when I clicked on the reply button. Is there an explanation for this, or am I missing something?
I am building an todo app with Register, Login, Logout functionalities, I created a TaskForm to let user create their tasks, but when is click add it gives an
IntegrityError at / NOT NULL constraint failed: tasks_task.user_id
I tried many different approaches but it gives the same error
it works when i add user in fields in TaskForm but it creates a Dropdown list of All users
tasks/models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Task(models.Model):
name = models.CharField(max_length=200)
completed = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="tasks")
def __str__(self):
return f"{self.name}:{self.user}"
tasks/forms.py
from django import forms
from .models import Task
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = [
'name',
]
tasks/views.py
from django.shortcuts import render, redirect
from .forms import TaskForm
from .models import Task
from django.contrib.auth.decorators import login_required
# Create your views here.
#login_required
def home(request):
tasks = Task.objects.all()
if request.method == "POST":
form = TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
form = TaskForm()
context = {
'tasks': tasks,
'form': form,
}
return render(request, "tasks/home.html", context )
tasks/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name= 'home' )
]
home.html
{% extends 'users/layout.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container pt-5 ">
{% if user.is_authenticated %}
<p style="text: 'center'">User: {{ user.get_username }}</p>
<div class="container">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4" >Create Task</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</form>
</div>
{% else %}
Login Here
{% endif %}
<div class = "container">
<ul>
{% for task in tasks %}
{% if task in user.tasks.all %}
<li>{{ task.name }}</li>
{% endif %}
{% empty %}
<li>No Tasks for Today</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
forms.py
from django import forms
from .models import Task
class TaskForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
task = super(TaskForm, self).__init__(*args, **kwargs)
self.fields['user'].required = False
class Meta:
model = Task
fields = [
'name',
'user'
]
views.py
# You can save the user with form object then
#login_required
def home(request):
tasks = Task.objects.all()
if request.method == "POST":
form = TaskForm(request.POST)
if form.is_valid():
form_obj = form.save(commit=False)
form_obj.user = request.user
form.save()
return redirect('home')
form = TaskForm()
context = {
'tasks': tasks,
'form': form,
}
return render(request, "tasks/home.html", context )
For some reason, my forms.py doesn't view any of the fields, instead, it only shows the 'Add' button and I don't know what to do anymore. I'd really appreciate if someone who knows what they're doing could tell me what I did, or didn't do.
Please note that I'm new to Django, thank you.
Here's my views.py:
from django.shortcuts import render
from django.utils import timezone
from .models import Measurement
from .forms import MeasurementForm
from django.views import generic
class IndexView(generic.ListView):
model = Measurement
context_object_name = 'measurement_list'
template_name = 'index.html'
queryset = Measurement.objects.all()
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
return render(request, 'index.html', {'form': form})
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
forms.py:
from django import forms
from .models import Measurement
class MeasurementForm(forms.ModelForm):
class Meta:
model = Measurement
fields = ('measurement_value', 'measurement_unit')
index.html:
{% extends "base.html" %}
{% block content %}
<h1>Climate Measurement Tool</h1>
<h2>Add a new measurement</h2>
<form method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save">Add</button>
</form>
<h2>Measurements</h2>
{% if measurement_list %}
<ul>
{% for measurement in measurement_list %}
<li>
<p>{{ measurement }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>No measurements yet</p>
{% endif %}
{% endblock %}
The new_measurement() view correctly initializes a form instance and passes it to the template.
Unfortunately, that view is never called.
urls.py defines only one url, handled by IndexView.as_view(), which does not pass a form instance to the template.
Hello I'm new to Django and I am trying to build a simple e-commerce application. In this app I want a user to upload a photo of an item which they want to sell. I want to display all the items in the home page, when you hit on the item name it redirects to the item details page. User can add a new item with the following fields title, item image, and a description. I want to show a thumbnail of the uploaded image in the home page near the title and the original image in the item details page, but when I try to do this the image is not appearing in the details page. Here is my code:
models.py
from __future__ import unicode_literals
from django.db import models
from django.utils import timezone
from PIL import Image
class Item(models.Model):
posted_user = models.ForeignKey('auth.User')
item_name = models.CharField(max_length=200)
item_image = models.ImageField(upload_to='img')
item_discription = models.TextField()
posted_date = models.DateTimeField(
default=timezone.now)
forms.py
from django import forms
from .models import Item
import re
from django.contrib.auth.models import User
class SellItemAddForm(forms.ModelForm):
class Meta:
model = Item
fields = ('item_name', 'item_discription', 'item_image')
urls.py
from django.conf.urls import url
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', views.item_list, name='item_list'),
url(r'^item/(?P<pk>\d+)/$', views.item_detail, name='item_detail'),
url(r'^item/new/$',views.item_new, name='item_new'),
url(r'^item/(?P<pk>\d+)/edit$', views.item_edit, name='item_edit'),
url(r'^item/(?P<pk>\d+)/remove/$', views.item_remove, name='item_remove'),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
from django.shortcuts import render, get_object_or_404
from .models import Item
from django.utils import timezone
from .forms import SellItemAddForm
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
def item_list(request):
items = Item.objects.filter(posted_date__lte=timezone.now())
return render(request, 'sbApp/item_list.html',{'items': items})
def item_detail(request, pk):
item = get_object_or_404(Item, pk=pk)
return render(request, 'sbApp/item_detail.html', {'item': item})
def item_remove(request, pk):
item = get_object_or_404(Item, pk=pk)
item.delete()
return redirect('item_list')
#login_required
def item_new(request):
if request.method == "POST":
form = SellItemAddForm(request.POST)
if form.is_valid():
item = form.save(commit=False)
item.posted_user = request.user
item.posted_date = timezone.now()
item.save()
return redirect('item_detail', pk=item.pk)
else:
form = SellItemAddForm()
return render(request, 'sbApp/new_item.html', {'form': form})
#login_required
def item_edit(request, pk):
item = get_object_or_404(Item, pk=pk)
if request.method == "POST":
form = SellItemAddForm(request.POST, instance=item)
if form.is_valid():
item = form.save(commit=False)
item.posted_user = request.user
item.posted_date= timezone.now()
item.save()
return redirect('item_detail', pk=item.pk)
else:
form = SellItemAddForm(instance=item)
return render(request, 'sbApp/item_edit.html', {'form': form})
item_detail.html
{% extends 'sbApp/base.html' %}
{% block content %}
<div class="item">
{% if user.is_authenticated %}
<a class="btn btn-default" href="{% url 'item_remove' pk=item.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
<a class="btn btn-default" href="{% url 'item_edit' pk=item.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
{% endif %}
<h1>{{ item.item_name }}</h1>
{% if item.posted_date %}
<div class="date">
<p>posted on {{ item.posted_date }}</p>
</div>
{% endif %}
<div class="user_name">
<p>by {{item.posted_user}}</p>
</div>
<img src="{{ MEDIA_URL }}{{ item.item_image.url }}" alt="img">
<p>{{ item.item_discription|linebreaksbr }}</p>
</div>
{% endblock %}
item_list.html
{% extends 'sbApp/base.html' %}
{% block content %}
{% for item in items %}
<div class="item">
<h1>{{ item.item_name }} </h1>
<div class="date">
<p>posted on: {{ item.posted_date }}</p>
</div>
<p>{{ item.discription }}</p>
<img src="{{ MEDIA_URL }}{{ item.item_image.url }}" alt="img">
</div>
{% endfor %}
{% endblock %}
In your browser, look at the source code for the template where the img tag is, and let us know what is the value of the src attribute? My only guess is you are missing a / in there somewhere in the template {{ MEDIA_URL }}{{ item.item_image.url }}. Assuming the image exists and the MEDIA_URL constant is defined somewhere.
edit:
<img src="/{{ MEDIA_URL }}{{ item.item_image.url }}" alt="img">
^
it sounds like you have formed a relative URL, so one fix would be to make it an absolute URL by adding a / as shown above.
{{ MEDIA_URL }} you can checkout at template what the output of it, before combined with {{ item.item_image.url }}