I have this code on my template:
{% extends "base.html" %}
{% block content %}
<div style="padding:40px;margin:40px;border:1px solid #ccc">
<h1>picture</h1>
<form action="" method="post" enctype="multipart/form-data"> <!--{% url 'imageupload' %}-->
{% csrf_token %} {{form}}
<input type="submit" value="Upload" />
</form>
{% for img in images %}
{{forloop.counter}}.{{ img.pic.name }}
({{img.upload_date}})<hr />
{% endfor %}
</div>
{% endblock content %}
Although I have doubts with the form action but anyways.
The problem is that when I click on submit button, it takes me to a blank page, no pop-up to actually upload the image, nothing.
Is there some example I should follow to accomplish this?
Also, this is just a proof test, but I'd like to know if a model and/or form is actually needed for it to work?
EDIT
Okay, by editing the input line like this <input type="file" name='input_name' /> it actually opens the file pop-up, but obviously it doesn't upload anything, it needs like a submit button or something, so, now it looks like this:
{% extends "base.html" %}
{% block content %}
<div style="padding:40px;margin:40px;border:1px solid #ccc">
<h1>picture</h1>
<form action="" method="post" enctype="multipart/form-data"> <!--{% url 'imageupload' %} -->
{% csrf_token %} {{form}}
<input type="file" name='input_name' />
<input type="submit" value="Upload" />
</form>
{% for img in images %}
{{forloop.counter}}.{{ img.pic.name }}
({{img.upload_date}})<hr />
{% endfor %}
{% endblock content %}
But when I click on submit, it keeps sending me to a blank page, so, the value on submit, which is Upload, comes from this model:
from django.db import models
from django.forms import ModelForm
class Upload(models.Model):
pic = models.FileField(upload_to="static/")
upload_date=models.DateTimeField(auto_now_add =True)
class UploadForm(ModelForm):
class Meta:
model = Upload
fields = ('pic',)
And on my views.py:
from django.shortcuts import render
from uploader.models import UploadForm,Upload
from django.http import HttpResponseRedirect
from django.urls import reverse
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
return HttpResponseRedirect(reverse('imageupload'))
else:
img=UploadForm()
images=Upload.objects.all()
return render(request,'image_upload.html',{'form':img,'images':images})
And in my urls.py:
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic import TemplateView
from django.views import defaults as default_views
from uploader import views as uploader_views
urlpatterns = [...
some patterns...
url(r'^image_upload/', uploader_views.home, name='imageupload'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Related
I have followed an online tutorial to add a like button to my website/index html file, but for some reason it is not showing on the site. It must be witht the url or views files, but I can not figure it out. Below is the code. The models that I am trying to pull are migrated and work. If anybody has any tips that I could try I woudl greatly apprechiate it.
views file:
**from django.shortcuts import render, redirect
from django.http import JsonResponse
import json
import datetime
from .models import *
from .utils import cookieCart, cartData, guestOrder
from .models import Post, Like
# Create your views here.
def index(request):
return render(request, 'index.html', {})
def post_view(request):
qs = Post.objects.all()
user = request.user
context = {
'qs': qs,
'user': user,
}
return render(request, 'posts/postlike.html', context)
def like_post(request):
user = request.user
if request.method == 'POST':
post_id = request.POST.get('post_id')
post_obj = Post.objects.get(id=post_id)
if user in post_obj.liked.all():
post_obj.liked.remove(user)
else:
post_obj.liked.add(user)
like, created = Like.objects.filter(user=user, post_id=post_id)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
return redirect('post-list')**
urls file:
**from django.urls import path
from . import views
from .views import post_view, like_post
urlpatterns = [
path('', views.index, name='index'),
path('store/', views.store, name='store'),
path('postlike/', post_view, name='post-list'),
path('like/', like_post, name='like-post'),
]**
This is the postlike.html that I am extending into the main index website to create the like button for some of my picture, but it is not pulling.
*
*{% extends 'index.html' %}
{% block title %}
{% endblock title %}
{% block content %}
{% for obj in qs %}
<h1>{{ obj.title }}</h1>
<p>{{ obj.body }}</p>
<form action="{% url 'like-post' %}" method='POST' class="ui form">
{% csrf_token %}
<input type='hidden' name='post_id' value="{{ obj.id }}">
{% if user not in obj.liked.all %}
<button class="UI button positive" type='submit'>Like</button>
{% else %}
<button class="ui button negative" type='submit'>Unlike</button>
{% endif %}
</form>
<strong>{{ obj.liked.all.count }}</strong>
{% endfor %}
{% endblock content %}**
Index.html (which is my main homepage). I added the extends blocks to clarify where to add as well.
**{% block title %}
{% endblock title %}
{% block content %}
{% endblock content %}**
I am making a simple todolist application but while I am trying to create user specific pages, I am unable to add a new task probably beacause database is not getting all required datas(i.e. owner of the task).
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class value(models.Model):
task=models.CharField(max_length=200)
complete=models.BooleanField(default=False)
created=models.DateTimeField(auto_now_add=True)
owner=models.ForeignKey(User,on_delete=models.PROTECT)
def __str__(self):
return self.task
views.py
from http.client import HTTPResponse
from urllib import response
from django.shortcuts import render,redirect
from todo.models import value
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
# Create your views here.
from .forms import TitleForm
from django.urls import reverse
from django.contrib.auth.models import User
def home(request):
values=value.objects.all()
form=TitleForm()
if request.method=='POST':
form=TitleForm(request.POST)
if form.is_valid():
new_data=form.save(commit=False)
new_data.owner=request.user()
new_data.save()
return HttpResponseRedirect('/')
context={'form':form,'values':values}
return render(request,'home.html',context)
#update
def update(request,id):
ggwp=value.objects.get(id=id)
form=TitleForm(instance=ggwp)
if request.method == 'POST':
form=TitleForm(request.POST,instance=ggwp)
if form.is_valid:
form.save()
return redirect('home')
context={'form':form,}
return render(request,'update.html',context)
#delete
def delete_data(request, id ):
if request.method=="POST":
ggwp=value.objects.get(id=id)
ggwp.delete()
return HttpResponseRedirect(reverse('deldata', kwargs={'id':id}))
return redirect("/")
forms.py
from django import forms
from django.forms import ModelForm
from .models import value
from django import forms
class TitleForm(forms.ModelForm):
class Meta:
model= value
fields='__all__'
urls.py(app)
from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns=[
path('',views.home,name='home'),
path('delete/<str:id>', views.delete_data,name='deldata'),
path('update/<str:id>',views.update,name='update')
]
home.html(main page)
<form method="POST">
{% if user.is_authenticated %}
Hello,{{user.username}}<br>
Logout
{% else%}
Register
login
{% endif %}
</form>
<div class="p-3 mb-2 bg-warning text-dark" style="text-align: center;">
<form action="/" method="post" >
{% csrf_token %}
{{form.task}}
<input class='btn btm-sm btn-info' type='submit' name='add' value="add" >
</form>
{% for val in values %}
{% if val.complete == True %}
<s>{{val}}</s>
{% else %}
<span>{{val}}</span>
{% endif %}
<form action="{% url 'deldata' val.id %}" method="POST" class="in-line">
{% csrf_token %}
<input class='btn btm-sm btn-danger' type="submit" name="delete" value="delete">
<a class='btn btm-sm btn-info' href="{% url 'update' val.id %}" >Update</a>
</form>
{% endfor %}
</div>
Home.html looks like this:
todo
When i want to add a task and click on add, nothing really happens. It only redirects back to same page but not data is inserted in database.
If there are problems in questions, I am really sorry!
Home.html :
<div class = "divname">
{% if user.is_authenticated %}
Hello,{{user.username}}<br>
Logout
{% else%}
Register
login
{% endif %}
</div>
<div class="p-3 mb-2 bg-warning text-dark" style="text-align: center;">
<form method="POST" >
{% csrf_token %}
{{form}}
<input class='btn btm-sm btn-info' type='submit' name='add' value="add" >
</form>
{% for val in values %}
{% if val.complete == True %}
<s>{{val}}</s>
{% else %}
<span>{{val}}</span>
{% endif %}
<form action="{% url 'deldata' val.id %}" method="POST" class="in-line">
{% csrf_token %}
<input class='btn btm-sm btn-danger' type="submit" name="delete" value="delete">
<a class='btn btm-sm btn-info' href="{% url 'update' val.id %}" >Update</a>
</form>
{% endfor %}
</div>
UPDATE1 : EXCLUDING USER IN FORM AND ADDING THE CURRENT USER IN VIEWS
#Do not add Owner into the model form fields
forms.py:
from django import forms
from django.forms import ModelForm
from .models import value
from django import forms
class TitleForm(forms.ModelForm):
class Meta:
model= value
fields=['task', 'complete', 'created']
Views.py:
def home(request):
values=value.objects.all()
form=TitleForm()
if request.method=='POST':
form=TitleForm(request.POST)
if form.is_valid():
new_data=form.save(commit=False)
new_data.owner=request.user
new_data.save()
return HttpResponseRedirect('/')
context={'form':form,'values':values}
return render(request,'home.html',context)
Currently I have a user log in page and a user sign up page, how can I have both of these on one single page?
Base.html:
<!doctype html>
<head>
{% block head %}
<title>base</title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
signup.html:
{% extends 'core/base.html' %}
{% block head %}
<title> Sign Up</title>
{% endblock %}
{% block body %}
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}
login.html:
{% extends 'core/base.html' %}
{% block head %}
<title> Login</title>
{% endblock %}
{% block body %}
<h1>Login</h1>
<form method = 'post'>
{% csrf_token %}
{{ form.as_p }} <!--'form' comes from login view imported in urls-->
<button type = 'submit'>Login</button>
</form>
{% endblock %}
urls.py:
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.views import login
from core import views as core_views
urlpatterns = [
url(r'^$', core_views.login_redirect, name = 'login_redirect'),
url(r'^admin/', admin.site.urls),
url(r'^login/$', login, {'template_name': 'core/login.html'}, name='login'),
url(r'^signup/$', core_views.signup, name='signup'),
url(r'^account/$', core_views.account_page, name = 'account_page')
]
views.py:
from django.shortcuts import render
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.forms import UserCreationForm
def login_redirect(request):
return redirect('login')
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/account')
else:
form = UserCreationForm()
args = {'form': form}
return render(request, 'core/signup.html', args)
def account_page(request):
return HttpResponse('success')
How would I put both the log in and sign up on one page, if they are handled by separate views? Thank you in advance for your response! I have no more details to add and it is making me add more details i apologize for this unnecessary text.
In any scenario where you need multiple forms in the same page the following technique can be applied.
For example currently you need two forms 'Sign In' and 'Sign Up' on the same page.
index.html
<!-- Sign In Form -->
<form>
<button type='submit' name='submit' value='sign_in'></button>
</form>
<!-- Sign Up Form -->
<form>
<button type='submit' name='submit' value='sign_up'></button>
</form>
views.py
def index(request):
if request.method == "POST":
if request.POST.get('submit') == 'sign_in':
# your sign in logic goes here
elif request.POST.get('submit') == 'sign_up':
# your sign up logic goes here
I am new to Django. I created a simple createview and then tried the updateview likewise but I got the NoReverseMatch Error. I tried many ways suggested online but still they didnt seem to work.
This is the screenshot of the error I am getting NoReverseMatchError
Below are my files
urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from mapp import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^$',views.AboutView.as_view(),name='about'),
url(r'^blogs/$',views.BlogsView.as_view(),name='blog'),
url(r'^project/$',views.ProjectListView.as_view(),name='project_list'),
url(r'^project/(?P<pk>\d+)/$',views.ProjectDetailView.as_view(),name='project_detail'),
url(r'^project/create/$',views.ProjectCreateView.as_view(),name='project_create'),
url(r'^project/(?P<pk>\d+)/$',views.ProjectUpdateView.as_view(),name='update'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Views.py
from django.shortcuts import render,redirect
from django.views.generic import TemplateView,ListView,DetailView,CreateView,UpdateView
from mapp.models import Project
from mapp.forms import ProjectCreateForm,ProjectUpdateForm
# Create your views here.
class AboutView(TemplateView):
template_name='about.html'
class BlogsView(TemplateView):
template_name='blogs.html'
class ProjectListView(ListView):
model=Project
class ProjectDetailView(DetailView):
model=Project
class ProjectCreateView(CreateView):
model=Project
form_class=ProjectCreateForm
redirect_field_name='mapp/project_detail.html'
class ProjectUpdateView(UpdateView):
model=Project
form_class=ProjectUpdateForm
redirect_field_name='mapp/project_detail.html'
Project_detail.html
{% extends 'base.html'%}
{% block content %}
<h1>Project Details</h1>
<div class="container">
<h2>{{project.pname}}</h2>
<img src="{{project.pimage.url}}"></img>
<h2>{{project.ptech}}</h2>
<h2>{{project.pdetails}}</h2>
</div>
<div class="container">
<p>Update
</div>
{% endblock %}
Forms.py
from django import forms
from mapp.models import Project
class ProjectCreateForm(forms.ModelForm):
class Meta:
model=Project
fields=('pname','pimage','ptech','pdetails')
class ProjectUpdateForm(forms.ModelForm):
class Meta:
model=Project
fields=('pname','pimage','ptech','pdetails')
Project_form.html
{% extends 'base.html' %}
{% block content %}
<form class="project-form" method="POST" enctype="multipart/form-data">
<div class="jumbotron">
{% csrf_token %}
{{form.as_p}}
<button type="submit" class="save btn btn-default">Save</button>
</div>
</form>
{% endblock %}
Looks like your kwargs are not being passed to the view. Try changing self.id in your template to project.id
{% extends 'base.html'%}
{% block content %}
<h1>Project Details</h1>
<div class="container">
<h2>{{project.pname}}</h2>
<img src="{{project.pimage.url}}"></img>
<h2>{{project.ptech}}</h2>
<h2>{{project.pdetails}}</h2>
</div>
<div class="container">
<p>Update
</div>
{% endblock %}
Also your Detail and Update Views have the same url. Try adding something to make them different like
url(r'^project/detail/(?P<pk>\d+)/$',views.ProjectDetailView.as_view(),name='project_detail'),
url(r'^project/create/$',views.ProjectCreateView.as_view(),name='project_create'),
url(r'^project/update/(?P<pk>\d+)/$',views.ProjectUpdateView.as_view(),name='update'),
Or else it won't find the updateview.
I am trying to use Update view in django, in the simplest manner, but it is not being updated, rather a new object of the model is being created in the database. I have done the same thing for another model Track, and its working fine. I feel it might be something trivial that might be causing the problem.
I am modifying the PK of the model here. Could this be the reason?
View:
from django.views.generic.edit import UpdateView
from musictracker.models.datamodels.Genre import Genre
class EditGenre(UpdateView):
model = Genre
template_name = "editGenre.html"
fields = ['name']
Template:
{% extends 'base.html' %} {% load addcss %} {% block content %}
<div id="regContainer">
<ul>
<!-- {% if form.errors %} {{form.errors}} {% endif %} -->
</ul>
<div class="form-group">
<form method="post" action="">
{% csrf_token %}
{% for field in form %}
<label class="control-label" for="form-control input-sm">{{field.label_tag }}</label>
<br /> {{field|addcss:"form-control input-sm"}}
<br />
{% endfor %}
<input type="submit" id="register" value="Edit Genre" class="btn btn-default">
</form>
</div>
</div>
{% endblock %}
URLS.py
from django.conf.urls import url
from django.contrib import admin
''' View Imports '''
from views import TrackList
from views import AddTrack
from views import TrackDetail
from views import EditTrack
from views import GenreList
from views import GenreDetail
from views import AddGenre
from views import EditGenre
urlpatterns = [
url(r'^tracks/', TrackList.as_view(),name='all-tracks'),
url(r'^addTrack/', AddTrack.as_view(),name='add-tracks'),
url(r'^editTrack/(?P<pk>[0-9]+)', EditTrack.as_view(),name='edit-track'),
url(r'^track/(?P<pk>[0-9]+)', TrackDetail.as_view(),name='track'),
url(r'^genres/', GenreList.as_view(),name='all-genres'),
url(r'^addGenre/', AddGenre.as_view(),name='add-genre'),
url(r'^editGenre/(?P<pk>[a-zA-Z0-9]+)', EditGenre.as_view(),name='genre'),
url(r'^genre/(?P<pk>[a-zA-Z0-9]+)', GenreDetail.as_view(),name='genre'),
]
Model:
class Genre(models.Model):
'''
This is a model for Genres
'''
name = models.CharField(max_length=20,primary_key=True,editable=True)
songcount = models.IntegerField()
def __unicode__(self):
return self.name
def get_absolute_url(self):
return reverse('genre', kwargs={'pk': self.pk})
Well, as other folks said in comments, your view creates new object instead of update because you have editable primary key.
You see, undercover UpdateView creates form for your model and calls save on that form.
It's the save method of BaseModelForm which operates self.instance attribute. And if instance isn't being found by pk, new one will be created. So I suggest you to recreate your model with uneditable primary key and leave name as just simple char field.
For future visitors - I experienced the same issue, but did not have an editable primary key. In my case I reused a form for both CreateView and UpdateView and forgot to allow for the difference in form action:
<form role="form" class="form-horizontal" action="{% url createobject' %}" method="post" multipart/form-data">
But it should have been
{% if not object %}
<form role="form" class="form-horizontal" action="{% url 'object:createobject' %}" method="post" multipart/form-data">
{% else %}
<form role="form" class="form-horizontal" action="{% url 'object:updateobject' object.pk %}" method="post" enctype="multipart/form-data">
{% endif %}
So, whenever I submitted the form, the action called my Createview instead of my UpdateView.