django Form组件之解决数据无法动态显示之BUG----以博客园添加新随笔页为主
在定义Form组件类的时候,自定义__init__方法, 在__init__方法上重新取一下数据,即每次实例时取到的都是最新的数据
以下以博客园添加新随笔(即编写博客页面)的前端Html为例
views.py中的Form组件定义的类
1 current_user = "" 2 class ArticleEditor(Form): # 定义类 3 title = fields.CharField(max_length=64) # 文章标题 4 content = fields.CharField(widget=widgets.Textarea(attrs={"id": "i1"})) # 文章内容,后台结合beautifulSoup模块,生成富文本编辑框 5 type_choices = [ # big_type列的choices的内容,即系统分类的具体类名, 6 (1, "Python"), 7 (2, "Linux"), 8 (3, "OpenStack"), 9 (4, "GoLang"), 10 ] 11 big_type = fields.IntegerField(widget=widgets.RadioSelect(choices=type_choices)) # 系统分类,公共类别, 单选只能时其中一类 12 category = fields.ChoiceField(widget=widgets.RadioSelect,choices=models.Category.objects.filter(blog__user__username=current_user). 13 values_list("nid", "title")) # 个人分类,此处设置为只能属于某一个类别,注意这列的choices定义在了下面的__init__里实例化时重新获取了一次 14 tag = fields.ChoiceField(widget=widgets.RadioSelect,choices=models.Tag.objects.filter(blog__user__username=current_user). 15 values_list("nid", "title")) # 个人标签,此处设置为只能属于某一个标签,注意这列的choices定义在了下面的__init__里实例化时重新获取了一次 16 17 def __init__(self, request, *args, **kwargs): # 自定义__init__方法,传入request参数便于从session中获取code 18 super(ArticleEditor, self).__init__(*args, **kwargs) 19 self.request = request 20 global current_user # 当前用户名全局 21 current_user = request.session.get("username") 22 print("当前用户", current_user) 23 self.fields["category"].choices = models.Category.objects.filter(blog__user__username=current_user).values_list("nid", "title") 24 self.fields["tag"].choices = models.Tag.objects.filter(blog__user__username=current_user).values_list("nid", "title") 25 26 def clean_content(self): # 在form组件中过滤textarea中的非法输入, 27 content = self.cleaned_data["content"] 28 valid_tag = { # 标签白名单 所允许的在textarea文本框中出现的标签及奇属性 29 "p": ["class", "id"], 30 "img": ["src"], 31 "div": ["class"] 32 } 33 soup = BeautifulSoup(content, "html.parser") # 将字符串转化为beautifulsoup对象 34 tags = soup.find_all() # 找出所有对象,对象集合,[] 35 for tag in tags: 36 if tag.name not in valid_tag: # 判断表示是否在白名单 37 tag.decompose() # 不在白名单就删除这个标签 38 if tag.attrs: # 如果标签存在属性 39 for k in tag.arrts.keys(): # 与下行一起遍历此tag的属性有无不在白名单中此标签的属性 40 if k not in valid_tag[tag.name]: 41 del tag.attrs[k] # 不在的话就删除这个属性 42 content_str = soup.decode() # 由soup对象转化为字符串 43 return content_str # 以上这个过程可以封装在一个函数中,可取名家XSS组件
views.py中url对应的函数:
1 def article_editor(request): 2 try: 3 if request.method == "GET": 4 obj = ArticleEditor(request) 5 return render(request, "article_editor.html", {"obj": obj}) 6 else: 7 obj = ArticleEditor(request, request.POST) 8 blog_id = models.Blog.objects.filter(user__username=current_user).first().nid 9 if obj.is_valid(): 10 with transaction.atomic(): 11 content = obj.cleaned_data.get("content") 12 print("内容:", content) 13 title = obj.cleaned_data.get("title") 14 big_type = int(obj.cleaned_data.get("big_type")) 15 category = int(obj.cleaned_data.get("category")) 16 tag = int(obj.cleaned_data.get("tag")) 17 summary = content[0:200] 18 print("简介:", summary) 19 20 models.Article.objects.create(title=title, summary=summary, article_type_id=big_type, blog_id=blog_id, 21 category_id=category) 22 article_id = models.Article.objects.filter(title=title, summary=summary).first().nid 23 models.Article2Tag.objects.create(article_id=article_id, tag_id=tag) 24 models.ArticleDetail.objects.create(content=content, article_id=article_id) 25 return redirect("/blog/%s/articles/?article_nid=%s" % (current_user, article_id)) # 返回发表后的这个文章,未作继续编辑 26 else: 27 print("校验失败") 28 return render(request, "article_editor.html", {"obj": obj}) 29 # return render(request, "article_editor.html", {"obj": obj}) 30 except Exception as e: 31 return HttpResponse(str(e))
简单的前端HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #i2{ width: auto; } .item1{ width: 700px; } </style> </head> <body> <div> <form method="post" action="/article_editor/" novalidate> {% csrf_token %} <p>文章标题</p> <p class="item1"> {# <input type="text" name="title" placeholder="文章标题">#} {{ obj.title }} {{ obj.errors.title.0 }} </p> <p> {# <textarea id="i1" name="content"></textarea>#} {{ obj.content |safe}} </p>{{ obj.errors.content.0 }} <p>系统类别</p> <p>{{ obj.big_type }}</p>{{ obj.errors.big_type.0 }} <p>个人分类</p> <p>{{ obj.category }}</p>{{ obj.errors.category.0 }} <p>个人标签</p> <p>{{ obj.tag }}</p>{{ obj.errors.tag.0 }} <p> <input type="submit" value="提交"> </p> </form> </div> </body> <script src="/static/plugin/kindeditor-4.1.10/kindeditor-all.js"></script> <script> KindEditor.create("#i1",{ width:"700px", height:"400px", uploadJson:"/upload_file/", extraFileUploadParams:{ "csrfmiddlewaretoken":"{{ csrf_token }}" } }) </script> </html>