I am trying to build a CRM in Django and in doing so I am trying to add a place to add comments to a lead. I created a form and upon submitting a comment I get directed to the 401 page where I am greeted with an error. On the 401 page it references my form.save() in my views. Please help.
401 Error
"Field 'id' expected a number but got 'some'."
. I will post my code below
Below is my info view which is used to display information about a particular lead
def info(request, pk):
info = lead.objects.get(id=pk)
form = lead_comment()
if request.method == 'POST':
form = lead_comment(request.POST)
if form.is_valid():
form.save()
return redirect('info.html')
context={'info':info, 'form': form}
return render(request, 'info.html', context)
My URLS
from django.urls import path
from . import views
urlpatterns = [
path('', views.dashboard, name='dashboard'),
path('leads/', views.leadsPage, name='leads'),
path('docs/', views.docsPage, name='docs'),
path('add-lead/', views.addLead, name='add-lead'),
path('leads/<str:pk>/', views.info, name='description'),
]
My info.html
{% include 'navbar.html' %}
<body class="dash">
<div class="navdash">
<div class="container-lead">
<div class="lead-space">
<h2>{{ info.first }} {{ info.last }}</h2>
<h5>Phone number: {{ info.phnum }}</h5>
<h5>Email: {{ info.email }}</h5>
</div>
<body>
<form method="POST" action="">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Submit" />
</form>
</body>
</div>
</div>
</body>
My lead model where I have am initializing comment
class lead(models.Model):
first=models.CharField(max_length=20)
last=models.CharField(max_length=20)
email=models.CharField(max_length=30)
phnum=models.CharField(max_length=10)
associate=models.ForeignKey(agent, on_delete=models.CASCADE, default='some' )
comment=models.CharField(max_length=500, blank=True, null=True)
def __str__(self):
return self.first + ' ' + self.last
My Form
class lead_comment(ModelForm):
class Meta:
model=lead
fields=['comment']
Try adding the following lines to your info views:
def info(request, pk):
i = lead.objects.get(id=pk)
form = lead_comment(instance=i)
if request.method == 'POST':
form = lead_comment(request.POST, instance=i)
if form.is_valid():
form.save()
return redirect('info.html')
context={'i':i, 'form': form}
return render(request, 'info.html', context)
Related
I was getting that same error while click the like button, But the error was solved..
again after creating comment view and its other staff I'm getting that error again...When I click the comment button then the error appears..I'm very new to Django,,, help me please..
My project models.py, template page, urls.py, views.py are attached herewith
**models.py**
from email.policy import default
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Blog(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200, verbose_name="Put a Title")
blog_content = models.TextField(verbose_name="What is on your mind")
blog_image = models.ImageField(upload_to="blog_images", default = "/default.png")
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Comment(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_comment" )
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_comment")
comment = models.TextField()
comment_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.comment
class Like(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_liked")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_liked")
class Unlike(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_unliked")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_unliked")
**blog_page.html**
{% extends "main.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
<div style="text-align:center;">
<h2>{{blog.title}}</h2>
<img src="{{blog.blog_image.url}}" alt="" width="630px" height="300px">
</div>
<div style="text-align:center;">
{{blog.blog_content|linebreaks}}
</div>
{% if not liked and not unliked %}
<h4> Like </h4>
<h4>Unlike</h4>
{% elif unliked %}
<h4> Like </h4>
{% elif liked %}
<h4>Unlike</h4>
{% endif %}
<div>
<h4>
Comments:
</h4>
{% for comment in comments %}
<div>
{{ user }} <br>
<h5>{{ comment }}</h5>
</div>
{% endfor %}
<!-- <h6>Add your comment:</h6> -->
<form action="" method="POST">
{% csrf_token %}
{{form|crispy}} <br>
<a class="btn btn-sm btn-info" href="{% url 'comment' %}">Comment</a>
</form>
</div>
{% endblock content %}
**urls.py**
from django.urls import path
from blog_app import views
urlpatterns = [
path("", views.home, name='home'),
path("blog_page/<str:pk>/", views.blog_view, name='blog_page'),
path("like/<str:pk>/", views.like, name="like"),
path("unlike/<str:pk>/", views.unlike, name="unlike"),
path("comment/", views.comment, name="comment"),
]
**views.py**
from django.shortcuts import render
from . models import Blog, Comment, Like, Unlike
from . forms import CommentForm
# Create your views here.
def home(request):
blogs = Blog.objects.all()
context = {'blogs': blogs}
return render(request, 'blog_app/home.html', context)
def blog_view(request, pk):
blog = Blog.objects.get(id=pk)
form = CommentForm()
comments = Comment.objects.filter(blog=blog)
context = {"blog": blog, "comments": comments, "form":form}
return render(request, 'blog_app/blog_page.html', context)
def like(request, pk):
blog = Blog.objects.get(id=pk)
user = request.user
liked, like = Like.objects.get_or_create(blog=blog, user=user)
context = {"liked" : liked, "blog": blog }
return render(request, "blog_app/blog_page.html", context)
def unlike(request, pk):
blog = Blog.objects.get(id=pk)
user = request.user
unliked, unlike = Unlike.objects.get_or_create(blog=blog, user=user)
context = {"unliked" : unliked, 'blog': blog}
return render(request, "blog_app/blog_page.html", context)
def comment(request):
form = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
form.save()
context = {}
return render(request, "blog_app/blog_page.html", context)
Your comment button is just a link, is it normal ? I think, you want to submit your form when you click on?
<div>
<h4>
Comments:
</h4>
{% for comment in comments %}
<div>
{{ user }} <br>
<h5>{{ comment }}</h5>
</div>
{% endfor %}
<!-- <h6>Add your comment:</h6> -->
<form action="{% url 'comment' %}" method="POST">
{% csrf_token %}
{{form|crispy}} <br>
<button type="submit" class="btn btn-sm btn-info">Comment</button>
</form>
</div>
And i think, your problem occured because you dispolay this template from comment view without set blog in context data.
def blog_view(request, pk):
blog = Blog.objects.get(id=pk)
form = CommentForm()
comments = Comment.objects.filter(blog=blog)
context = {"blog": blog, "comments": comments, "form":form}
return render(request, 'blog_app/blog_page.html', context)
def comment(request):
form = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
form.save()
return redirect("blog_page", pk=form.instance.blog.pk)
return HttpResponse(status_code=400) # error case
else:
return HttpResponse(status_code=501) # try to GET page
Better solution is to pass blog pk in the url for being able to render page with error:
path("blog/<int:pk>/comment/", views.comment, name="comment")
<form action="{% url 'comment' blog.pk %}" method="POST">
{% csrf_token %}
{{form|crispy}} <br>
<button type="submit" class="btn btn-sm btn-info">Comment</button>
</form>
def comment(request, pk):
blog = get_object_or_404(Blog, pk=pk)
form = CommentForm()
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
form.save()
return redirect("blog_page", pk=blog.pk)
return render(request, "...", {"blog": blog, "form": form})
In my app, I have created a context_proccessors.py to show the form to base.html file.
I am able to show the form in the base.html file. But the problem I am facing is I have no idea how to save that form data from base.html since there is no view for the base.html. Below is my code:
models.py
class Posts(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_posts')
post_pic = models.ImageField(upload_to='post_pic', verbose_name="Image")
post_caption = models.TextField(max_length=264, verbose_name="Caption")
created_date = models.DateTimeField(auto_now_add=True)
edited_date = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.user.username}"
forms.py
from django import forms
from post_app.models import Posts
class PostForm(forms.ModelForm):
class Meta:
model = Posts
exclude = ('user',)
context_proccessors.py
from post_app.forms import PostForm
def post_form(request):
form = PostForm
return {
'post_form': form,
}
base.html
<form method="POST" enctype="multipart/form-data">
{{ post_form|crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-primary">Post</button>
</form>
I want the form to be displayed on every page so that the user can submit data from anywhere
def PostView(request):
form = PostForm()
if request.method == 'GET':
return render(request, 'base.html', {form:form})
elif request.method == 'POST':
form.save(request.data)
In the views.py of your app you can define this view, and the you have to provide it an url in the urls.py of the root directory. So evere time there is a request on that url, if the method is GET, the form will be rendered on base.html file, if the method is POST, the post will be saved.
By following the answer by N T I have implemented this. So, I had to make a URL pattern for the view and use that URL pattern in the action in the form of base.html.
view.py
#login_required
def postsaveview(request):
form = PostForm()
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
user_obj = form.save(commit=False)
user_obj.user = request.user
user_obj.slug = str(request.user) + str(uuid.uuid4())
user_obj.save()
return HttpResponseRedirect(reverse('profile_app:profile'))
urls.py
urlpatterns = [
path('post-save/', views.postsaveview, name='post-save'),
]
base.html
<form action="{% url "post-save" %}" method="POST" enctype="multipart/form-data">
{{ post_form|crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-primary">Post</button>
</form>
I am trying to update my homepage whenever a new "article" is added, however it is giving me this error whenever I try to update the page using my updateHomepage view it doesn't work and I get the error
TemplateSyntaxError at /
Could not parse the remainder: ' 'update_homepage'' from 'url 'update_homepage''
I am very new to django so any help with this would be amazing.
My Views.py
def index(request):
articles = Article.objects.all()
context = {'articles': articles}
return render(request, 'able/homepage.html', context)
def updateHomepage(request, pk):
form = EditorForm(instance=task)
context = {'form': form}
article = Editor.objects.get(id=pk)
return render(request, 'able/update_homepage.html', context)
if request.method == 'POST':
form = EditorForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
def editorview(request):
editor = EditorForm
context = {'editor': editor}
return render(request, 'able/editor.html', context)
if request.method == 'POST':
form = EditorForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
urls.py
urlpatterns = [
path('', views.index, name='homepage'),
path('editor/', views.editorview),
path('update_homepage/<str:pk>/', views.updateHomepage, name='update_homepage')
]
homepage.html
<h1>My Blog</h1>
{% for article in articles %}
<div class="article">
{% csrf_token %}
<h1>{{ article.title }}</h1>
<h3>{{ article.text }}</h3>
</div>
{% endfor %}
Update
update_homepage.html
<h3>Update Homepage</h3>
<form action="" method="POST">
{% csrf_token %}
{{form}}
<input type="submit">
</form>
I am trying to implement the login field using django's authenticationForm.
the problem im having is that,because im trying to display two different forms inside one page (post_list) it seem to cause many errors.
one is for login field, and one is for the posting articles.
i also seem to have problem with duplicate forms as the two forms use the samename for the form which i do not know how to change.
also, there an error occurring when i try to post something using the post form.
to blatantly put, how do i make the login field visible?
i refer you to the working site : http://mtode.com( this is just a representation site, and do not contain login field part)
this is my views py which contains the definitions
from django.contrib import messages
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
from .forms import PostForm, AuthenticationForm
from .models import Post
from django.contrib.auth import authenticate, login
from django.contrib.auth import login
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
from django.contrib.auth.decorators import login_required
def post_detail(request, id=None):
#instance = Post.objects.get(id=1)
instance = get_object_or_404(Post, id=id)
context = {
"title": instance.title,
"instance": instance,
}
return render(request, "post_detail.html", context)
def post_list(request):
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
login(request, form.get_user())
return HttpResponseRedirect('/post-list/')
else:
form = AuthenticationForm(request)
return TemplateResponse(request, 'login.html', {'form': form})
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
print (form.cleaned_data.get("title"))
instance.save()
# message success
messages.success(request, "Successfully Created")
return HttpResponseRedirect(instance.get())
#else:
#messages.error(request, "Not Successfully Created")
queryset = Post.objects.all()#.order_by("-timestamp")
context = {
"object_list": queryset,
"title": "List",
"form": form,
}
return render(request, "post_list.html", context)
#return HttpResponse("<h1>List</h1>")
def post_update(request, id=None):
instance = get_object_or_404(Post, id=id)
form = PostForm(request.POST or None, instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
# message success
messages.success(request, "Saved")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"title": instance.title,
"instance": instance,
"form":form,
}
return render(request, "post_form.html", context)
def post_delete(request, id=None):
instance = get_object_or_404(Post, id=id)
instance.delete()
messages.success(request, "Successfully deleted")
return redirect("posts:list")
and this is the forms.py that contains the forms
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"title",
"content"
]
from django.contrib.auth import authenticate
class AuthenticationForm(forms.Form):
username = forms.CharField(max_length=254)
password = forms.CharField(widget=forms.PasswordInput)
def clean(self):
username = self.cleaned_data['username']
password = self.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is None:
raise forms.ValidationError('invalid_login')
return self.cleaned_data
and this is the post_list.html
{% extends "base.html" %}
{% block content %}
<form method="post" action="">
{% csrf_token %}
Username: {{ form.username }} {{ form.username.errors }}<br>
Password: {{ form.password }} {{ form.password.errors }}<br>
{{ form.errors }}<br>
<input type="submit" value="login" />
</form>
<div class='two columns right mgr'>
<h1>Form</h1>
<form method='POST' action=''>{% csrf_token %}
{{ form.as_p }}
<input class="button-primary" type='submit' value='Create Post' />
</form>
</div>
<div class='four columns left'>
<h1>{{ title }}</h1>
{% for obj in object_list %}
<div class="row">
<div>
<a href='{{ obj.get_absolute_url }}'>
<div class="thumbnail">
<!--<img src="..." alt="...">!-->
<div class="caption">
<h3>{{ obj.title }}<small> {{ obj.timestamp|timesince }} ago</small></h3>
<p>{{ obj.content|linebreaks|truncatechars:120 }}</p>
<!-- <p>View </p>-->
</div>
</div></a>
</div>
<hr />
</div>
{% endfor %}
</div>
{% endblock content %}
Thank you.
When your page is initially displayed, request.method is GET. Therefore the post_list view is creating a PostForm instance and passing that into your template as the form element.
PostForm does not have username or password attributes, so those items are treated as empty strings and do not render at all.
If you want a template to render two forms, you need to pass them as separate names. You can't call them both "form".
I cannot add a file in Django. When I click the "save" button, it does not save the database.
This is my view.py:
def add_product(request):
if request.method == "POST":
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.userprofile = request.user
post.save()
return redirect('kerajinan.views.add_product', pk=post.pk)
else:
form = PostForm()
return render(request, 'kerajinan/add_product.html', {'form': form})
add_product.html:
{% block content %}
<h1>New Product</h1>
<from method="POST" class="post-form" enctype="multiple/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</from>
{% endblock %}
forms.py:
class PostForm(forms.ModelForm):
class Meta:
model = Product
fields = ('category','title', 'price','image', 'description')
and urls.py:
url(r'^add_product/$', views.add_product, name='add_product'),
Can you help me solve my problem?
You need to change your enctype to: enctype="multipart/form-data"
Your current value (multiple/form-data), is not a valid method of encoding.
From the docs:
Note that request.FILES will only contain data if...the <form> that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.