i made a blog site sometime ago with python and django and used mysql as a database
the viewers can see all written blogs and comments ,but to write blogs and comments viewers have to login or signup ...thats all good but the problem is that when i want to edit or delete a blog or comment , any logged-in user can edit or delete any comment or blog , i want to implement user permissions so that only the user who wrote the blog /comment can edit /delete it ,not every one
my views
from django.shortcuts import render,redirect
from django.contrib.auth.models import User,auth
from django.contrib import messages
from app.models import signup,blog
from app.forms import CommentForm,Blogform
# Create your views here.
def signup1(request):
if request.method == "POST":
Realname = request.POST['realname']
Username = request.POST['username']
sEmail = request.POST['semail']
sPassword = request.POST['spassword']
if User.objects.filter(username=Username).exists():
messages.info(request, "user exists")
return redirect("/")
else:
user = User.objects.create_user(username=Username, email=sEmail, password=sPassword, first_name=Realname)
user.save()
auth.login(request, user)
print("user made")
return redirect("/")
else:
form1 = signup.objects.all()
return render(request, 'Signup.html', {'signup': form1})
def login(request):
if request.method == "POST":
username =request.POST['lgusername']
password =request.POST['lgpassword']
user =auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect("/")
else:
messages.info(request,"invalid username or password")
return redirect("/login")
else:
return render(request,"login.html")
def logout(request):
auth.logout(request)
return redirect("/")
def blog1(request):
blogs= blog.objects.all()
return render(request,'blog.html',{'blogs':blogs})
def blogdetail(request ,slug):
post =blog.objects.get(slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('post_detail', slug=post.slug)
else:
form = CommentForm()
return render(request,'blog_detail.html',{'post':post ,'form': form})
def writeblog(request):
if request.method == "POST":
form=Blogform(request.POST)
if form.is_valid():
try:
form.save()
return redirect('/')
except:
pass
else:
form=Blogform()
return render(request,"write.html",{'form':form})
def edit(request,slug):
edit =blog.objects.get(slug=slug)
return render(request,"edit.html",{'edit':edit})
def update(request,slug):
edit = blog.objects.get(slug=slug)
form = Blogform(request.POST, instance=edit)
if form.is_valid():
form.save()
return redirect("/")
return render(request, 'update.html', {"edit" :edit})
def delete(request,slug):
delete= blog.objects.get(slug=slug)
delete.delete()
return redirect('/')
////this is my template
{% extends "base.html" %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>blog</title>
</head>
<body>
{%block content%}
<div class="container">
<div class="d-flex align-items-center col-lg-12 col-md-12 col-sm-10 flex-column">
{% for blogs in blogs %}
<div style="width:100%;" class="border mt-3 border-secondary rounded">
<div class="container">
<h2 style="font-size:35px;" class="mr-auto rounded bg-secondary mt-2 pl-3 pb-2 pt-1 ">{{blogs.title}}</h2>
</div>
<small style="margin-left:4%;margin-bottom:4px;">posted at {{blogs.date_added}}</small>
<p style="margin-left:4%;margin-bottom:4px;"><strong>{{blogs.intro}}</strong></p>
<a style="margin-left:90%;" href="{% url 'post_detail' blogs.slug %}">Read more</a>
</div>
{% endfor %}
</div>
</div>
<a class="btn btn-primary" data-bs-toggle="offcanvas" href="#toggle" role="button" aria-controls="sidebar">
Link with href
</a>
<div class="offcanvas offcanvas-start" id="toggle">
<div class="offcanvas-header">
<h5 class="offcanvas-title"> Hello This is my offcanvas</h5>
<button type="button" class="btn-close" aria-label="sidebar-lable" data-bs-dismiss="offcanvas" ></button>
</div>
<div class="offcanvas-body">
<p>
this is the body of the offcanvas that i made just five minutes ago .
hello again
bye .
</p>
<form class="form-group ">
<label>Type your name</label>
<input placeholder="your name" class="form-control" type="text"><br>
<input type="submit" class="btn btn-outline-success">
</form>
</div>
</div>
{%endblock%}
</body>
</html>
my urls
from django.urls import path
from . import views
urlpatterns=[
path('signup',views.signup1,name="signup"),
path('login',views.login,name="login"),
path('logout',views.logout,name="logout"),
path('',views.blog1,name="blog"),
path('write',views.writeblog,name='write')
]
my models
from django.db import models
# Create your models here.
class signup(models.Model):
Realname = models.CharField(max_length=100)
Username = models.CharField(max_length=100)
sEmail = models.EmailField(max_length=150)
sPassword = models.CharField(max_length=250)
class Meta:
db_table ="Signupusers"
def __str__(self):
return self.Realname
class blog(models.Model):
title =models.CharField(max_length=250)
slug =models.SlugField()
intro =models.TextField()
body= models.TextField()
writer=models.TextField()
date_added=models.DateTimeField(auto_now_add=True)
class Meta:
db_table="blog1"
ordering =['-date_added']
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(blog, related_name='comments', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
email = models.EmailField()
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
db_table="comments"
ordering = ['date_added']
Related
I'm doing my first question on StackOverFlow about something ig going me crazy.
My project is an Auction site, and is based on django and Web3 to interact with a smart contract deployed on my Ganache.
Now I have got this error on my view :
ValueError at /getGiftFromFaucet/ The view contract.views.getGiftFromFaucet didn't return an HttpResponse object. It returned None instead.
The problem is:
If I register a customer and an address,
then I try to receive tokens from the Faucet,
If I put customer address I don't receive anything.
But if i select another address, I receive token in the first address.
I really don't understand why...
my Model:
class Customer(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
address = models.CharField(max_length=256,
blank=False,
null=False,
unique=True,
error_messages={'unique': 'This address is already registered'})
tokenBalance = models.FloatField(default=0)
dollarBalance = models.FloatField(default=0)
my Registration to the site
def registrationForm(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
address = form.cleaned_data['address']
user = User.objects.create_user(
username=username,
password=password,
)
newCustomer = Customer(
user=user,
dollarBalance=random.randrange(500, 1500),
address=address,
tokenBalance=0
)
user.save()
newCustomer.save()
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, f'''Welcome in DNote {request.user}''')
return redirect('homepage')
else:
form = RegistrationForm()
context = {'form': form}
return render(request, 'registration.html', context)
my Form:
class ReceiveTokenFromFaucet(forms.ModelForm):
class Meta:
model = Customer
fields = ['address']
My view:
def getGiftFromFaucet(request):
customer = Customer.objects.get(user=request.user)
customerAddress = customer.address
if request.method == 'POST':
form = ReceiveTokenFromFaucet(request.POST)
if form.is_valid():
form.save(commit=False)
customerAddress = form.cleaned_data['address']
if customerAddress not in alreadyRecompensed:
contract.functions.transfer(
customerAddress, 100000000000000000000
).transact({'from': faucet})
alreadyRecompensed.append(customerAddress)
customer.tokenBalance += 100000000000000000000
customer.save()
messages.success(request, 'Your Tokens Are accreditate on your Account')
return redirect('/homepage/')
if customerAddress in alreadyRecompensed:
messages.error(request, 'Already Recompensed')
return redirect('/homepage/')
else:
form = ReceiveTokenFromFaucet()
context = {'form': form, 'alreadyRecompensed': alreadyRecompensed}
return render(request, 'requireFromFaucet.html', context)
My Html:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block head_title %}{{ block.super }} ReceiveFreeTokens {% endblock head_title %}
{% block content %}
<div class="row justify-content-center mt-4">
<div class="col-4">
<h2>DNote</h2>
<h3>Receive Free Tokens</h3>
<p>Available only one time</p>
<br>
<form method="POST" enctype="multipart/form-data" style="max-width:100%">
{% csrf_token %}
{{ form|crispy }}
<br>
<input type="submit" class="btn btn-info" value="Create">
</form>
</div>
</div>
{% endblock content %}
views.py
def postdetail(request,pk): # Single Post view.
post = Post.objects.get(id=pk)
comment = post.comments.all()
comment_count = comment.count()
if request.user.is_authenticated:
if request.method == 'POST':
form = CommentForm(data=request.POST)
content = request.POST['cMessage']
if form.is_valid():
print("Yes valid")
form.instance.body = content
new_comment = form.save(commit=False)
print(new_comment)
new_comment.post = post
new_comment.user = request.user
new_comment.save()
return redirect('blog-home')
else:
form = CommentForm()
context = {
'comment_form': CommentForm,
'post' : post,
'comments': comment,
'count': comment_count,
}
return render(request,'post/postdetail.html', context=context)
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
user = models.ForeignKey(User,on_delete=models.CASCADE, related_name='comments')
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
# active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return f'Comment by {self.user} on {self.post}'
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['body']
template
{% if request.user.is_authenticated %}
<!-- respond -->
<div class="respond">
<h3>Leave a Comment</h3>
<!-- form -->
<form name="contactForm" id="contactForm" method="post" action="">
{% csrf_token %}
<fieldset>
<div class="message group">
<label for="cMessage">Message <span class="required">*</span></label>
<textarea name="cMessage" id="cMessage" rows="10" cols="50" ></textarea>
</div>
<button type="submit" class="submit">Submit</button>
</fieldset>
</form> <!-- Form End -->
</div>
{% endif %}
There is no error being displayed neither If I am adding a comment using the shell/through admin panel but if I am trying to add the comment dynamically through the form then the comment is not getting saved.
I have added only the form in the template.
You have defined field body in your CommentForm. It's required in your form, because you didn't include blank=True argument in your model for this field. This means that when you POST request and check if form is valid with form.is_valid(), the form expects an element with a name body in the request. If it's not there, it will not validate and content won't be saved.
Make the following changes:
Change your view to
...
if request.method == 'POST':
form = CommentForm(data=request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.post = post
new_comment.user = request.user
new_comment.save()
return redirect('blog-home')
else:
print(form.errors) # or log it to a file, if you have logging set up
form = CommentForm()
...
Change your HTML to this:
...
<form name="contactForm" id="contactForm" method="post" action="">
{% csrf_token %}
<fieldset>
<div class="message group">
<label for="body">Message <span class="required">*</span></label>
<textarea name="body" id="cMessage" rows="10" cols="50" ></textarea>
{{ comment_form.body.errors }}
</div>
<button type="submit" class="submit">Submit</button>
</fieldset>
</form>
...
In views.py
def postdetail(request):
print(Comment.objects.all())
if request.method == 'POST':
form = CommentForm(data=request.POST)
content = request.POST['body']
if form.is_valid():
print("Yes valid")
new_comment = form.save(commit=False)
print(new_comment)
new_comment.post = post
new_comment.user = request.user
new_comment.save()
return redirect('blog-home')
else:
form = CommentForm()
return render(request,'temp/postdetail.html', context=context)
In html file
{% if request.user.is_authenticated %}
<div class="respond">
<h3>Leave a Comment</h3>
<form name="contactForm" id="contactForm" method="post" action="">
{% csrf_token %}
<textarea name="body"cols="30" rows="10"></textarea>
<button type="submit" class="submit">Submit</button>
</form>
</div>
{% endif %}
This worked for me.
i am new to django when i try to run this project i wasn't getting any input fields in my template current page was only showing the given labels
i don't know where i've gone wrong
can any of you guys help??
these are my models.py file
from django.db import models
# Create your models here.
class Student(models.Model):
sid = models.CharField(max_length=100)
sname = models.CharField(max_length=100)
sclass = models.CharField(max_length=100)
semail = models.EmailField(max_length=100)
srollnumber = models.CharField(max_length=100)
scontact = models.CharField(max_length=100)
saddress = models.CharField(max_length=100)
class Meta:
db_table = "student"
the are my forms.py file
from django import forms
from student.models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = "__all__"
these are my views.py file
from django.shortcuts import render
from student.models import Student
from student.forms import StudentForm
def student_home(request):
return render(request, 'employee/dash.html')
def add_student(request):
if request.method == "POST":
form = StudentForm(request.POST)
if form.is_valid():
try:
form.save()
return render(request, 'employee/dash.html')
except:
pass
else:
form = StudentForm()
return render(request, 'student/addstudent.html')
template
<!DOCTYPE html>
<html lang="en">
<head>
<title>addstudent</title>
</head>
<body>
<a href="/home" >home</a>
<form method="POST" action="/add_student">
{% csrf_token %}
<label>Student ID:</label>
{{ form.sid }}
<label>Name :</label>
{{ form.sname }}
<label>Class :</label>
{{ form.sclass }}
<label>Email ID:</label>
{{ form.semail }}
<label>Roll Number :</label>
{{ form.srollnumber }}
<label>Contact :</label>
{{ form.scontact }}
<label>Address :</label>
{{ form.saddress }}
<button type="submit">Submit</button>
</form>
</body>
</html>
You forget to give the context to the render function:
return render(request, 'student/addstudent.html',context={'form':form})
should work
You have not included any context in your render functions. Your view should be:
def add_student(request):
if request.method == "POST":
form = StudentForm(request.POST)
if form.is_valid():
try:
form.save()
return render(request, 'employee/dash.html', context={'form': form})
except:
pass
else:
form = StudentForm()
return render(request, 'student/addstudent.html', context={'form': form})
I made a custom UserCreationForm. I can signup but after that I can't login into my web app. I can only login as a superuser. I imported the LoginView() but when I try to login it tells me "Please enter a correct username and password. Note that both fields may be case-sensitive.".
[views.py]
#csrf_exempt
def signup(request):
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
print('found it')
profile.profile_pic = request.FILES['profile_pic']
profile.save()
# registered = True
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
return redirect('../')
else:
print(user_form.errors,profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request,'users/signup.html',
{'user_form':user_form,
'profile_form':profile_form,'registered':registered})
forms.py
class UserForm(UserCreationForm):
class Meta():
model = User
fields = ('username','email')
def __init__(self, *args, **kwargs):
super(UserCreationForm, self).__init__(*args, **kwargs)
for fieldname in ['username', 'password1', 'password2']:
self.fields[fieldname].help_text = None
class UserProfileInfoForm(forms.ModelForm):
class Meta():
is_photographer = forms.BooleanField()
model = UserProfileInfo
fields = ('portfolio_site','profile_pic', 'type_of_photography', 'is_photographer',)```
models.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
portfolio_site = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
is_photographer = models.BooleanField(default=False)
type_of_photography = models.CharField(max_length=120, blank=True)
def __str__(self):
return self.user.username
login.html
{% load staticfiles %}
{% block title %}
<title>Login</title>
<link rel="stylesheet" href="{% static 'css/login.css' %}"/>
{% endblock %}
{% block main %}
<div class="col-md-11 container login">
<div class="row">
<div class="col-md-7 left">
<div class="group">
<h1>Login</h1>
<h4>Welcome Back. Please login to your account.</h4>
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value = "login">Login</button>
</form>
</div>
</div>
<div class="col-md-5 right">
<div class="group">
<h1>Don't have an account?</h1>
<h4>Create one now!</h4>
<button>Sign up</button>
</div>
</div>
</div>
</div>
{% endblock %}
When I trying to add image from admin panel all OK, but when I trying to add image from site, I have this error: image of error. When I trying to post Detail without image, I have the same problem. Before this wasn't.
views.py:
def new_detail(request):
if request.user.is_authenticated:
if request.user.is_superuser:
if request.method == 'POST':
car = request.POST['car']
author = request.user
detail = request.POST['detail']
price = request.POST['price']
description = request.POST['description']
image = request.FILES['images']
detail = Detail(car = car, author = author, detail = detail, price = price, description = description, images = image)
detail.save()
return redirect('/new_detail/')
else:
return redirect('/login/')
return render(request, 'shop/new_detail.html')
new_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-8">
<div class=".signin">
<form action="" method="POST">
{% csrf_token %}
<h3>Автомобіль: </h3>
<select name="car">
<option selected>Audi A8 D2 3.3 TDI</option>
<option>Audi A8 D2 3.7</option>
...
...
...
<h3>Ціна: </h3><textarea name="price"></textarea>
<h3>Фотки: </h3><input type="image" name="images" />
<p>
<input type="submit" value="Опублікувати" />
</form>
</div>
</div>
</div>
models.py:
from django.db import models
class Detail(models.Model):
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,)
car = models.CharField(max_length=100)
detail = models.TextField()
description = models.TextField()
price = models.CharField(max_length=30)
images = models.ImageField(upload_to='details', null = True, blank = True)
def __unicode__(self):
return self.detail
def __str__(self):
return self.detail
The first problem is that you are missing enctype="multipart/form-data" from your form tag in the template. See the docs on file uploads for more info.
<form action="" method="POST" enctype="multipart/form-data">
Secondly, your view doesn't handle the case when data is missing from the form. Instead of doing request.POST['detail'] you should be checking if 'detail' in request.POST or using request.POST.get('detail').
However it would be very time consuming to check every field individually. You should look at Django forms and model forms, which can handle a lot of this for you.
from django import forms
class DetailForm(forms.ModelForm):
class Meta:
model = Detail
fields = ['car', 'author', 'detail', 'price', 'description', 'images']
Then your view will be something like
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(lambda u: u.is_superuser)
def new_detail(request):
if request.method == 'POST':
form = DetailForm(request.POST)
if form.is_valid():
detail = form.save()
return redirect('/new_detail/')
else:
form = DetailForm(request.POST)
return render(request, 'shop/new_detail.html', {'form': form})
You can use the form to simplify your template as well:
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
See the docs on rendering fields manually if you need more control in the template.