how to create django edit test and update test - python

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)

Related

How to delete entry in django?

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.

Class view with post, get and data

I have practically finished the microblogging application and I want to change to class base views now. I read about generic views, but it looks like each of them has specific properties. In my index view I display two models and two forms, so I created IndexView (View) and put the get and post functions there and it works, but it doesn't look like there are any benefits of class views, so I'm probably doing something wrong. Currently, several views repeat a lot of code, and I thought that class views would solve this problem. I would like an example of how such a view should be written as class view with reusable get.
class IndexView(View):
def get(self, request, *args, **kwargs):
post_form = AddPostForm()
comment_form = AddCommentForm()
if request.user.is_authenticated:
logged_user = CustomUser.objects.get(id=request.user.id)
blocked_users = logged_user.blocked.all()
posts = Post.objects.exclude(author__in=blocked_users)
print(blocked_users)
posts = posts.order_by('-pub_date')
else:
posts = Post.objects.all()
posts = posts.order_by('-pub_date')
comments = Comment.objects.all()
comments = comments.order_by("-pub_date")
return render(request, 'mikroblog/index.html', {'posts': posts, 'comments': comments,
'post_form': post_form, 'comment_form': comment_form})
def post(self, request, *args, **kwargs):
if request.method == 'POST':
post_form = AddPostForm(request.POST)
comment_form = AddCommentForm(request.POST)
if post_form.is_valid():
new_post = post_form.save(commit=False)
new_post.author = request.user
new_post.tags = ''
content = ''
for word in new_post.content_post.split():
if '#' in word:
new_post.tags += f"{word} "
content += f"{word} "
else:
content += f"{word} "
new_post.content_post = content
new_post.save()
for word in content.split():
if '#' in word:
print(word)
user_to_notificate = CustomUser.objects.get(username=word[1:])
new_notification = TalkAbout()
new_notification.where = new_post
new_notification._from = new_post.author
new_notification.to = user_to_notificate
new_notification.sended = False
print(new_notification)
new_notification.save()
post_form = AddPostForm()
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.author = request.user
new_comment.save()
comment_form = AddCommentForm()
return HttpResponseRedirect(reverse('index'))
Use class-based views and override the 'post' and 'get' methods if you need to.
Follow this link:
Django CBVs documentation

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.

How to create a unique reference for the result each time?

In general, I make a page on the site. The meaning is this: a person comes in, loads an xml file, selects several parameters, and outputs the result. I did not find how to handle the xml file at once. So I upload its file with the parameters to the database, and then redirect us to the page with the result. Everything works fine, but there is a problem. I have not figured out how to create a unique link for the result each time. Now I have one link for the results and it just shows the last one ...
views.py of uploader
def upload_file(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('lessons:index')
else:
form = DocumentForm()
return render(request, 'templates/upload/upload.html', {'form': form})
downloader
views.py of handler
def lessons_view(request):
a = keker()
return render(request, 'templates/lessons/ocenki.html', {'ocenki': a})
keker if handler function
Try code like this (python 3.6):
# models.py
class Document(Model):
...
reference = CharField(max_length=128, db_index=True, null=False)
...
# forms.py
import secrets
...
class DocumentForm(ModelForm):
...
def save(self, commit=True):
self.instance.reference = secrets.token_hex(128)
return super().save(commit)
# views.py
...
def upload_file(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('lessons:index', kwargs=dict(reference=form.instance.reference))
else:
form = DocumentForm()
return render(request, 'templates/upload/upload.html', {'form': form})
...
def lessons_view(request, reference):
a = keker(reference)
return render(request, 'templates/lessons/ocenki.html', {'ocenki': a})
# urls.py
...
url(r'^/(?P<reference>\w+)/$', 'index', name='index'),
...

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})

Categories