How to delete entry in django? - python

there is a small django project that has methods for creating a topic, creating and editing posts within it.
I don't understand how to write a method to delete a post in a topic
views.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
from django.http import Http404
#login_required()
def new_entry(request, topic_id):
topic = Topic.objects.get(id=topic_id)
check_topic_owner(topic.owner, request)
if request.method != "POST":
form = EntryForm()
else:
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return redirect('composetopic:topic', topic_id=topic_id)
context = {'topic': topic, 'form': form}
return render(request, 'composetopic/new_entry.html', context)
#login_required()
def edit_entry(request, entry_id):
entry = Entry.objects.get(id=entry_id)
topic = entry.topic
check_topic_owner(topic.owner, request)
if request.method != "POST":
form = EntryForm(instance=entry)
else:
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return redirect('composetopic:topic', topic_id=topic.id)
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'composetopic/edit_entry.html', context)
def check_topic_owner(owner, request):
if owner != request.user:
raise Http404
i was tried to add delete_entry() function, but its not working

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
from django.http import Http404
#login_required()
def delete_entry(request, topic_id):
try:
topic = Topic.objects.get(id=topic_id)
topic.delete()
except Topic.DoesNotExist as e:
topic = None
if request.method != "POST":
form = EntryForm()
else:
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic # <Topic: Topic object (None)> topic or None
return redirect('composetopic:topic', topic_id=topic_id) # deleted id
context = {'topic': topic, 'form': form} # <Topic: Topic object (None)> topic or None
return render(request, 'composetopic/deleted_entry.html', context)
topic should return a null queryset instance if has beed deleted correctly (id exist and object is validated) if is not is just set to None
from app.models import Topic
>>> Topic.objects.all()
<QuerySet [. . .]>
#...
>>> topic = Topic.objects.get(id = id)
>>> topic.delete()
<Topic: Topic object (None)> # You can still access to his attributes but this not exist in database
if id object is not valid, raise an error self.model.DoesNotExists then a try-except statement is used when you call get method, also when you check for type of request ("POST", "GET") you need to modify how and where redirect deleted objects or something like render a page with text 'deleted topic' and some information about deleted object.

Related

ValueError in Django Python Forum application

I'm trying to create a form where users can add a new topic within a category. Then the users will be able to comment on each topic. Everything was working up until I tried adding the form page for new_topic
The error I receive:
ValueError at /new_topic/
The view speak_space.views.new_topic didn't return an HttpResponse object. It returned None instead.
Heres the code for my view.py and urls.py files:
view.py
from django.shortcuts import render, redirect
from .models import Category
from .models import Topic
from .forms import TopicForm
def index(request):
"""The home page for speak_space"""
return render(request, 'speak_space/index.html')
def categories(request):
"""Show all categories."""
categories = Category.objects.order_by('date_added')
context = {'categories': categories}
return render(request, 'speak_space/categories.html', context)
def category(request, category_id):
"""Show a single category(tribe) and all of its topics(convos)."""
category = Category.objects.get(id=category_id)
topics = category.topic_set.order_by('-date_added')
context = {'category': category, 'topics': topics}
return render(request, 'speak_space/category.html', context)
def topics(request):
"""Show all topics within a category(tribe)."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'speak_space/topics.html', context)
def topic(request, topic_id):
"""Show a single topic(convo/post) and all of it's replies."""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'speak_space/topic.html', context)
def new_topic(request):
"""Add a new conversation topic."""
if request.method != 'POST':
# No data submitted; create a blank form.
form = TopicForm()
else:
# POST data submitted; process data.
form = TopicForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('speak_space:topics')
# Display a blank or invalid form.
context = {'form': form}
return render(request, 'speak_space/new_topic.html', context)
and heres my url file:
from django.urls import path
from . import views
app_name = 'speak_space'
urlpatterns = [
# Home page
path('', views.index, name='index'),
# Page that shows all categories
path('categories/', views.categories, name='categories'),
# Profile page for a category
path('categories/<int:category_id>/', views.category, name='category'),
# Page that shows all topics.
path('topics/', views.topics, name='topics'),
# Detail page for a single topic(conversation)
# Where you go after you click on someones post
path('topics/<int:topic_id>/', views.topic, name='topic'),
# Page for adding a new conversation topic
path('new_topic/', views.new_topic, name='new_topic'),
]
and my forms page:
from django import forms
from .models import Topic
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
Your new_topic view doesn't return anything in case of GET request. You shoud make return statement common:
def new_topic(request):
"""Add a new conversation topic."""
if request.method != 'POST':
# No data submitted; create a blank form.
form = TopicForm()
else:
# POST data submitted; process data.
form = TopicForm(data=request.POST)
if form.is_valid():
form.save()
return redirect('speak_space:topics')
# The changes are here, now return will work for all requests types POST and GET
context = {'form': form}
return render(request, 'speak_space/new_topic.html', context)
Deindent the following lines
# Display a blank or invalid form.
context = {'form': form}
return render(request, 'speak_space/new_topic.html', context)
inside your new_topic method.

Error in Basic User Permissions in Django blog

My simple Django blog don't work - if I go to http://127.0.0.1:8000/posts/create/ I see
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/posts/create/
Raised by: posts.views.post_create
Looking in the git history I understand what error in posts/views.py.
The file itself looks like this
from urllib.parse import quote
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.contrib import messages
from .forms import PostForm
from .models import Post
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
def post_create(request):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
form = PostForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, 'Successfully Created')
return HttpResponseRedirect(instance.get_absolute_url())
context = {
'form': form,
}
return render(request, 'posts/post_form.html', context)
def post_detail(request, id=None):
instance = get_object_or_404(Post, id=id)
share_string = quote(instance.content)
context = {
'title': instance.title,
'instance': instance,
'share_string': share_string
}
return render(request, 'posts/post_detail.html', context)
def post_list(request):
queryset_list = Post.objects.all()
paginator = Paginator(queryset_list, 5)
page = request.GET.get('page')
queryset = paginator.get_page(page)
context = {
'object_list': queryset,
'title': 'List'
}
return render(request, 'posts/post_list.html', context)
def post_update(request, id=None):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
instance = get_object_or_404(Post, id=id)
form = PostForm(request.POST or None, request.FILES or None,
instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, 'ItemSaved',
extra_tags='html_safe')
return HttpResponseRedirect(instance.get_absolute_url())
context = {
'title': instance.title,
'instance': instance,
'form': form
}
return render(request, 'posts/post_form.html', context)
def post_delete(request, id=None):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
instance = get_object_or_404(Post, id=id)
instance.delete()
messages.success(request, 'Successfully Deleted')
return redirect('posts:list')
I think error in if not request.user.is_staff or not request.user.is_superuser line.
Because after this line, if I understand correctly from history, django-blog not work.
django.VERSION - (2, 0, 1, 'final', 0)
Thank you very much.

Displaying Django Form Results

I have a Django Form (ModelForm) which has a number of fields. When the user presses submit these are then saved to a database. What I am struggling to work out is, how do I then output/render these results in some other HTML page.
Models.py
from django.db import models
# Create your models here.
class Contract(models.Model):
name = models.CharField(max_length=200)
doorNo = models.SlugField(max_length=200)
Address = models.TextField(blank=True)
Forms.py
from django import forms
from contracts.models import Contract
class GenerateContract(forms.ModelForm):
class Meta():
model = Contract
fields = '__all__'
Views.py
from django.shortcuts import render
from contracts.forms import GenerateContract
# Create your views here.
def index(request):
return render(request, 'contracts/index.html')
def contractview(request):
form = GenerateContract()
if request.method == "POST":
form = GenerateContract(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print('ERROR')
return render(request,'contracts/contracts.html',{'form':form})
At the moment, I am returning the 'Index' Home page of the app as a placeholder.
After validation, the form data is found in form.cleaned_data dictionary. So you can pass that back to the template and display it as you see fit.
from django.shortcuts import render
from contracts.forms import GenerateContract
# Create your views here.
def index(request):
return render(request, 'contracts/index.html')
def contractview(request):
form = GenerateContract()
if request.method == "POST":
form = GenerateContract(request.POST)
if form.is_valid():
form.save(commit=True)
return render(request,'contracts/contracts.html',{'form_data': form.cleaned_data})
else:
print('ERROR')
return render(request,'contracts/contracts.html',{'form':form})
If you want to show the form with the saved values, you can render the template with form and fill the instance input . like this:
from django.shortcuts import render
from contracts.forms import GenerateContract
# Create your views here.
def index(request):
return render(request, 'contracts/index.html')
def contractview(request):
form = GenerateContract()
if request.method == "POST":
form = GenerateContract(request.POST)
if form.is_valid():
saved_instance = form.save(commit=True)
return render(request,'contracts/contracts.html',{'form':GenerateContract(instance=saved_instance)})
else:
print('ERROR')
return render(request,'contracts/contracts.html',{'form':form})

how to create django edit test and update test

I have views.py like this
and than how to create edit test and update test?? i
want edit and update can do it by id
from django.shortcuts import render, redirect
from .models import People
def index(request):
peoples = People.objects.all()
context = {'peoples': peoples}
return render(request, 'people_app/index.html', context)
def create(request):
print(request.POST)
people_app = People(name=request.POST['name'], biography=request.POST['biography'])
people_app.save()
return redirect('/')
def edit(request, id):
people = People.objects.get(id=id)
context = {'people': people}
return render(request, 'people_app/edit.html', context)
def update(request, id):
people = People.objects.get(id=id)
people.name = request.POST['name']
people.biography = request.POST['biography']
people.save()
return redirect('/')
def destroy(request, id):
people = People.objects.get(id=id)
people.delete()
return redirect('/')
Edit or Update operations performed in POST request. As you have write definition based view you have to check for type of request and act accordingly.
def edit(request, id):
people = People.objects.get(id=id)
if request.method == 'POST':
people.<field_to_update> = request.POST.get('<field_value>')
people.save()
context = {'people': people}
return render(request, 'people_app/edit.html', context)

Page Processor is not working

processors.py file:
from django import forms
from django.http import HttpResponseRedirect
from mezzanine.pages.page_processors import processor_for
from .models import Author
class AuthorForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
#processor_for(Author)
def author_form(request, page):
form = AuthorForm()
if request.method == "POST":
form = AuthorForm(request.POST)
if form.is_valid():
# Form processing goes here.
redirect = request.path + "?submitted=true"
return HttpResponseRedirect(redirect)
return {"form": form}
here define urls.py file where i define processor like:
url("^xyz/$", "mezzanine.pages.views.page", {"slug": "Author"}, name="Author"),
The form still doesn't display. How do I solve this error?
Mistake: Always define processor name in " " like #processor_for("Author")
**#processor_for("Author")**
def author_form(request, page):
form = AuthorForm()
if request.method == "POST":
form = AuthorForm(request.POST)
if form.is_valid():
# Form processing goes here.
redirect = request.path + "?submitted=true"
return HttpResponseRedirect(redirect)
return {"form": form}

Categories