the image uploaded is not stored on the database - django

i'm creating a 'create an account view ' which the user can store his image, name ,lastname ....
on my database the name,lastname... are registred but the image is not stored.why?
in models.py:
from django.db import models
class information(models.Model):
name=models.CharField(max_length=50)
lastname=models.CharField(max_length=50)
email=models.CharField(max_length=50)
password=models.CharField(max_length=50)
img=models.ImageField(upload_to='media',blank=True)
in forms.py:
from app1.models import information
from django import forms
class create_form(forms.ModelForm):
class Meta:
model=information
fields=[
'name',
'lastname',
'email',
'password',
'img'
]
in views.py:
def create_view(request,*args,**kwargs):
my_form=create_form(request.POST or None)
if my_form.is_valid():
my_form.save()
print(my_form.cleaned_data['img'])**#########print :None**
context={"form":my_form}
return render(request,'first create.html',context )
in templates:
<main>
<section>
<form action="" method="Post"> {% csrf_token %}
{{form.as_p}}
<input type="submit" value="save"/>
</form>
</section>
</main>
url.py
from django.contrib import admin
from django.urls import path
from app1 import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', views.firstview, name='home'),
path('Create/', views.create_view, name='create'),
path('home/main/', views.homeview, name='main')
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

You made two mistakes here. First of all, you need to pass request.FILES to the form:
from django.shortcuts import redirect
def create_view(request,*args,**kwargs):
if request.method == 'POST':
my_form=create_form(request.POST, request.FILES)
if my_form.is_valid():
my_form.save()
return redirect('some-view')
else:
my_form = create_form()
context={'form': my_form}
return render(request,'first create.html', context)
and furthermore you need to specify enctype="multipart/form-data" in your <form> tag:
<main>
<section>
<form action="" method="Post" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="save"/>
</form>
</section>
</main>
Note that you better implement the Post/Redirect/Get pattern [wiki] and thus make a redirect(..) [Django-doc] in case of a succesful POST request.

Related

Django image uploading error, "This field is required', "no files chosen"

I was working on a django project. I made a userprofiles app to manage(create, update) user's profile in my website, but it is not working properly. I am getting 'This field is required' &
'no file chosen' while making profile as a user and if I do blank=True in models profile_picture user pictures are not saving in the media url.
I have tried so many tips from stackoverflow but they are not working.
here is my code:
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))
# models.py
from django.db import models
from django.contrib.auth import get_user_model
import uuid
class UserProfile(models.Model):
author = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='images/')
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
bio = models.TextField(blank=True)
occupation = models.CharField(max_length=100)
hobbies = models.TextField(blank=True)
date_of_birth = models.TimeField()
def __str__(self):
return self.author.username + ("'s profile")
# views.py
from django.views.generic import CreateView
from .forms import CustomUserCreationForm
from django.urls import reverse_lazy
class SignUpView(CreateView):
form_class = CustomUserCreationForm
template_name = "registration/signup.html"
success_url = reverse_lazy("profile_create")
# project-level urls.py
from django.contrib import admin
from django.conf import settings
from django.urls import path, include
from django.conf.urls.static import static
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path("accounts/", include("accounts.urls")),
path("accounts/", include("django.contrib.auth.urls")),
path("profile/", include("userprofiles.urls")),
path("", TemplateView.as_view(template_name="home.html"), name="home"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# app-level urls.py
from django.urls import path
from .views import ProfileCreateView
urlpatterns = [
path("create/", ProfileCreateView.as_view(), name="profile_create")
]
# profile_create.html
{% extends 'base.html' %}
{% block title %}Create Your Profile{% endblock title %}
{% block content %}
<h2>Create Your Profile</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create my profile</button>
</form>
{% endblock content %}
tell me what is the problem with it, I am stucked out of it, Thank you
I believe you missed enctype in html form,
enctype="multipart/form-data"
from docs,
Note that request.FILES will only contain data if the request method
was POST, at least one file field was actually posted, and the
that posted the request has the attribute
enctype="multipart/form-data". Otherwise, request.FILES will be empty.
HTML form should be,
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create my profile</button>
</form>

Log out when sending a form

I've created an app where you can make comment (which sends a form to a database and saves it) if you're login on only, but when I press the button "Create" instead of redirecting me to the page where it show all the comments, it logs me out and bring me back to the "log out" view (which is / )
the create Template:
{% extends 'base.html' %}
{% block content %}
<div class="create_comment">
<h2>Write a comment</h2>
<form class="site-form" action="{% url 'create' %}" method="post">
{% csrf_token %}
{{form}}
<input type="submit" value="Create">
</form>
</div>
{% endblock %}
The Views of Create:
#login_required(login_url='/userprofile/login/')
def comments_create(request):
if request.method == 'POST':
form = forms.CreateComment(request.POST)
if form.is_valid():
form.save()
return redirect('/usercomments')
else:
form = forms.CreateComment()
return render(request,'usercomments/comments_create.html', {'form':form})
Log out view:
def logout_view(request):
if request.method == 'POST':
logout(request)
return redirect('/')
else:
pass
usercomments Urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.comments_list, name="list"),
url(r'^create/$', views.comments_create, name="create"),
url(r'^(?P<slug>[\w-]+)/$',views.comments_detail, name="detail"),
]
userprofile urls.py:
from django.conf.urls import url
from . import views
app_name = 'userprofile'
urlpatterns = [
url(r'^signup/$', views.signup_view, name="signup"),
url(r'^login/$', views.login_view, name="login"),
url(r'^logout/$',views.logout_view, name="logout"),
]

update an object without DetailView Django

I'm looking for a solution to update an object without having to go to the detail page but, just edit it on the page itself. What I want to achieve is when I click on edit: the object becomes a field where I can edit and save it. All the YouTube tutorials show the edit->detail page version.
So a quick/direct edit on the object itself that is on the homepage without leaving the homepage.
I have tried to use the UpdateView on this but then there is separate HTML file necessary, which would result in leaving the homepage. I would like to get some help or tips on this.
urls.py
from django.urls import path
from .views import (
HomePageView,
TaskCreateView,
TaskDeleteView,
TaskUpdateView,
)
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('task_new/', TaskCreateView.as_view(), name='task_new'),
path('<int:pk>/task_delete/', TaskDeleteView.as_view(), name='task_delete'),
path('<int:pk>/task_edit/', TaskUpdateView.as_view(), name='task_edit'),
]
views.py
from django.views.generic import ListView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.urls import reverse_lazy
from .models import Task
class HomePageView(ListView):
model = Task
template_name = 'home.html'
context_object_name = 'all_tasks_list'
class TaskCreateView(CreateView):
model = Task
fields = ['text',]
class TaskDeleteView(DeleteView):
model = Task
success_url = reverse_lazy('home')
class TaskUpdateView(UpdateView):
model = Task
fields = ['text',]
home.html
<!DOCTYPE html>
<html>
<head>
<title>Todo app</title>
</head>
<body>
<h1>Todo app</h1>
<ul>
{% for task in all_tasks_list %}
<li>{{ task.text }}</li>
<form action="{% url 'task_delete' task.pk %}" method="post">{% csrf_token %}
<input type="submit" value="Delete"/></form>
<form action="{% url 'task_edit' task.pk %}" method="post">{% csrf_token %}
<input type="submit" value="Edit"/>
</form>
{% endfor %}
</ul>
<form action="{% url 'task_new' %}" method="post">{% csrf_token %}
<input type="text" name="text"/>
<input type="submit" value="Add"/>
</form>
</body>
</html>
models.py
from django.db import models
from django.urls import reverse
class Task(models.Model):
text = models.TextField()
def __str__(self):
return self.text[:50]
def get_absolute_url(self):
return reverse('home')
The error says task_form.html doesn´t exist, default template for an UpdateView. Are you sure it exists? If you want to use another template you have to specify
class TaskUpdateView(UpdateView):
model = Task
fields = ['text',]
template_name = 'todoapp/my_template.html'
Considering you are using generic view you should follow documentation for UpdateView
In this particular case you are missing form that UpdateView looks for to render GET request
The UpdateView page displayed to a GET request uses a
template_name_suffix of '_form'.
In your particular case it is todoapp/task_form.html which you should create
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update"> </form>

Request is not getting into views, but its shows the corret url

Form is loaded in html page but when i click submit button,it shows nothing(No HttpResponse which i used in views). But it show url(http://localhost:8000/datainsert )as i described in urls.py. Please point out what's wrong in my code.
forms.py
from django import forms
from .models import Test
class TestForm(forms.ModelForm):
class Meta:
model = Test
fields = '__all__'
views.py
def datainsert(request):
if request.method == 'POST':
form = TestForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse('Saved')
return HttpResponse('Not saved')
urls.py
from django.conf.urls import url
from . import views
from .views import index, datainsert, testing
urlpatterns = [
url(r'^', views.index, name='index'),
url(r'^datainsert', views.datainsert, name='datainsert'),
]
index.html
<html>
<head>
<title>My Web</title>
</head>
<body>
<form action="{% url 'myapp:datainsert' %}" method="POST">
{% csrf_token %}
{{form}}
<button type="submit">Submit</button>
</form>
</body>
</html>
You didn't terminate your empty URL.
url(r'^$', views.index, name='index')
Currently it matches every possible path.

Django: Troubles uploadind and handling an image (CSRF token missing or incorrect)

I'm just trying to practice with Django. I tried to make a simple app which allows you to upload an image and return the pixelated version of it.
I have two views: one to show the form and one to handle the image and return the result.
The problem is that a 'Forbidden (403)' is raised instead of the result. Reason given for failure: CSRF token missing or incorrect.
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^result/$', views.pixelate, name='pixelate')
]
views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from .forms import UploadImageForm
from .pixelate import pixelate_image
def index(request):
form = UploadImageForm()
return render_to_response('pixelate/index.html', {'form': form})
def pixelate(request):
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
response = HttpResponse(content_type='image/png')
response['Content-Disposition'] = 'filename="image.png"'
img = pixelate_image(request.FILES['image'])
response.write(img)
return response
pixelate.py
from PIL import Image
from io import BytesIO
def pixelate_image(img, pixelSize=9):
buffer = BytesIO()
p = Image(buffer)
image = p.open(img)
image = image.resize((image.size[0]/pixelSize, image.size[1]/pixelSize), Image.NEAREST)
image = image.resize((image.size[0]*pixelSize, image.size[1]*pixelSize), Image.NEAREST)
image.save()
final_image = buffer.getvalue()
buffer.close()
return final_image
forms.py
from django import forms
class UploadImageForm(forms.Form):
image = forms.ImageField()
index.html
<form action="{% url 'pixelate:pixelate' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
index.html
<form action="{% url 'pixelate:pixelate' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>