django crud
第14部分 (Part-14)
Moving back to our blogapp, we had defined some views as follows
回到我们的Blogapp,我们定义了一些视图,如下所示
def home(request): content={'posts':Post.objects.all()} return render(request, 'blogapp/home.html',content)def post(request): return HttpResponse('<h1>A detailed post..</h1>')def create(request): return HttpResponse('<h1>Create a new post</h1>')def update(request): return HttpResponse('<h1>Update your post..</h1>')def delete(request): return HttpResponse('<h1>Delete a post..</h1>')
There are many more things to do here.., implement update, delete ,create new or view detailed post.Let’s use class based views here
这里还有更多的事情要做..,实现更新,删除,创建新的或查看详细的帖子。让我们在这里使用基于类的视图
Class based views have many built-in functionalities,let’s use them to allow users to create,read,update or delete a post using CreateView, DetailView or ListView, UpdateView and DeleteView
基于类的视图具有许多内置功能,让我们使用它们来允许用户使用CreateView,DetailView或ListView,UpdateView和DeleteView创建,阅读,更新或删除帖子。
Import these views in the blogapp/views.py as follows,
如下将这些视图导入blogapp / views.py中,
from django.views.generic import CreateView, ListView, UpdateView, DeleteView, DetailView
DetailView
详细视图
We want to show detailed view of any post in their respective pages or at </post/primary_key> and to do that let’s replace the post function with this
我们想在其各自的页面或</ post / primary_key>中显示任何帖子的详细视图,并为此替换该帖子功能。
class PostDetailView(DetailView): model = Post # blogapp/post_detail.html template_name='blogapp/details.html' context_object_name = 'post'
create your details.html and at the urlpattern, import the class from .views and add
创建您的details.html并在urlpattern处,从.views导入类并添加
from .view import PostDetailViewpath("post/<int:pk>", PostDetailView.as_view(), name="post-detail"),
remember to call .as_view() method of the class and the <int:pk> passes the primary key of the post to the url
记住要调用该类的.as_view()方法,并且<int:pk>将帖子的主键传递给url
The DetailView requires the model it should work on the default template name is as follows
DetailView要求它应使用默认模板名称的模型如下
<app_name>/<model>_<viewtype>.html
<app_name> / <model> _ <viewtype> .html
or in this case it will be
否则在这种情况下
blogapp/post_detail.html
blogapp / post_detail.html
the default context_object_name will be object so renaming our details.html to post_detail.html and using the default context_object_name we can shrinkour class as follows
默认的context_object_name将是对象,因此将我们的details.html重命名为post_detail.html并使用默认的context_object_name可以按如下所示缩小类
class PostDetailView(DetailView): model = Post
and in post_details.html
以及在post_details.html中
{% load humanize %}<img src="{{post.bg_pic.url}}"><div> <h3>{{post.title}}</h3> <p>{{post.content}}</p> <div class="date">Published {{post.date_posted|naturaltime}}</div> <div class="tags"> <div class="tag">By {{post.author}}</div> </div></div>
ListView
列表显示
Let’s replace our home function
让我们替换我们的home功能
we’ve been passing Post.objects.all to our page but setting model to the Post will do this job for us , and to order the posts according to the date we pass the ordering attribute {the -at the beginning arranges from the recent to the last one}
我们一直在将Post.objects.all传递到我们的页面,但是将模型设置为Post将为我们完成这项工作,并根据我们传递ordering属性的日期来对帖子进行排序{-开头是从最近到最后一个}
class HomeView(ListView): model = Post context_object_name = 'posts' template_name = 'blogapp/home.html' ordering = ['-date_posted']
Just decided to leave the name of the index page as home.html and used posts to keep the things simple here,the urlpattern for this will be
刚决定将索引页面的名称保留为home.html,并在此处使用了帖子以使事情保持简单,为此的urlpattern将是
path('', PostListView.as_view(), name=’blog-home’),
CreateView
创建视图
Let’s replace our create function
让我们替换我们的create函数
class PostCreateView(CreateView): model = Post fields = ['title','content','bg_pic']
here we specify the fields which we want our users to add.The default template name for this view will be different as post_form.html.Now import this in the urls.py and
在这里,我们指定希望用户添加的字段。此视图的默认模板名称将与post_form.html不同。 现在将其导入urls.py和
path("post/create/new",PostCreateView.as_view(),name='create'),
Do not forget to add the enctype in the form to set bg_pic
不要忘记在表单中添加enctype来设置bg_pic
When you test this view you might notice that when you try to submit it yells at you with
测试此视图时,您可能会注意到,当您尝试提交该视图时,您会大吼大叫
an Integrity error{not null constraint failed}
完整性错误{不是没有null约束失败}
well that’s because we are trying to create a post without an author.Let’s override this validation form and add the author before submission
那是因为我们试图创建一个没有作者的帖子,让我们覆盖此验证表单并在提交之前添加作者
def form_valid(self, form): form.instance.author=self.request.user return super().form_valid(form)
we assigned the current user as the author to the form and called the Parent class form_valid method again with the new form,and test again..,
我们将当前用户指定为表单的作者,并使用新表单再次调用Parent类form_valid方法,然后再次进行测试。
The ImproperlyConfigured error says that it successfully created the post but doesn’t where to redirect now, and also gives a hint to either redirect to a url or create a get_absolute_url ,let’s use the former one.In Models.py
ImproperlyConfigured错误表示它已成功创建了帖子,但现在没有重定向的位置,并且还提示您重定向到url或创建get_absolute_url,让我们使用前一个。
from django.urls import reversedef __str__(self): ...def get_absolute_url(self): return reverse('post-detail',kwargs={'pk':self.pk})
Redirect Method will redirect you to a specific route in General. Reverse Method will return the complete URL to that route as a String
重定向方法会将您重定向到常规的特定路由。 反向方法将以字符串形式返回到该路由的完整URL
Obviously we want an authenticated user to create a post we used @login_required decorator in function view but in class based views we’ll use loginmixin, In views.py ,import this and pass it to our class
显然,我们希望通过身份验证的用户创建一个在函数视图中使用@login_required装饰器的帖子,但在基于类的视图中,我们将使用loginmixin,在views.py中,将其导入并将其传递给我们的类
from django.contrib.auth.mixins import LoginRequiredMixinclass PostCreateView(LoginRequiredMixin,CreateView): .....
when someone try creating post as an anonymous user, and they will be redirected to the login url
当有人尝试以匿名用户身份创建帖子时,他们将被重定向到登录网址
UpdateView
更新视图
For updating the post we’ll keep our class functionality same and just change the name of our class, keep the same html file for the view ,import it in the urls and give it a name and we’re good to go.
为了更新帖子,我们将保持类的功能不变,只是更改类的名称,为视图保留相同的html文件,将其导入url中并为其命名,然后我们就可以开始了。
Not really ,we want only the authors of the post to be able to update or delete a post and not any random logged in user ,let’s use another mixin for that and pass it to update view class and define(rewrite) test_func function
并非如此,我们只希望帖子的作者能够更新或删除帖子,而不希望任何随机登录的用户,请为此使用另一个mixin并将其传递给更新视图类并定义(重写)test_func函数
PostUpdateView(LoginRequiredMixin,UserPassesTestMixin,UpdateView): .... def test_func(self): post=self.get_object() return self.request.user==post.author
and that’s it
就是这样
DeleteView
删除视图
Add the UserPassesTest and LoginRequired mixin to this view
将UserPassesTest和LoginRequired混合添加到此视图
class PostDeleteView(LoginRequiredMixin,UserPassesTestMixin,DeleteView): model = Post success_url = '/' def get_test_func(self): post=self.get_object() return self.request.user==post.author
the default template name for this will be post_confirm_delete.html
默认模板名称为post_confirm_delete.html
{% extends "blogapp/base.html" %}{% block body %} <form method="POST"> {% csrf_token %} <fieldset class="form-group"> <legend class="border-bottom mb-4">Delete Post</legend> <h2>Are you sure you want to delete the post "{{ object.title }}"</h2> </fieldset> <div class="form-group"> <button class="btn btn-outline-danger" type="submit">Yes, Delete</button> <a class="btn btn-outline-secondary" href="{% url 'post-detail' object.id %}">Cancel</a> </div> </form>{% endblock body %}
Now in base.html, we can add new post link under if user.is_authenticated and under detailed page(post_detail), add the update or delete functionality something like this..
现在在base.html中,我们可以在if.user_is_authenticated下和详细页面(post_detail)下添加新的帖子链接,添加更新或删除功能。
<div> {%if object.author==user%} <a href="{%url 'update' object.id%}">Update</a> <a href="{%url 'delete object.id'%}">Delete</a></div>
翻译自: https://medium.com/swlh/implement-crud-in-our-django-app-1c9109591f0c
django crud