我的博客,欢迎阅读 https://blog.starmeow.cn
Redis记录历史表单数据,之后读取填充选择表单
需求,在创建博客时,对于表单中的选择框每次都需要重新选,如果是发布同一类型的文章,分类、专题、标签都是一样,那么如何记录上次该浏览器的选择呢?
image.png- 创建博客时将浏览器选择的历史记录在Redis中;
- 视图中尝试读取该值,并在前端selected选中。
新建博客视图
创建验证form_valid(self, form)
成功后将选择项保存到redis数据库中,并设置过期时间为12小时
对于多选框,需要将结果值转换为以_
连接的字符串,'_'.join(map(lambda tag: str(tag.id), form.cleaned_data.get('tags')))
存储到Redis中。
当再次创建时,获取Redis中的值,对于多选,需要字符串分解了int型的列表select_tags = list(int(tag_id) for tag_id in last_select_tags.split('_'))
前端option
中通过tag.id in select_tags
判断是否是选中状态。
# 文章创建
@method_decorator(login_required, name='dispatch')
class BlogCreate(CreateView):
model = Article
template_name = 'rearend/blog-edit.html'
form_class = ArticleForm
from utils.project_config import get_redis_db
redis_db = get_redis_db()
# success_url = 'xxx' # 可以设置创建成功后跳转地址,也可以使用下面的函数
def get_success_url(self):
# print(self.object.id) # 可以得到新创建的博客id
# return reverse('blog:blog_list')
return reverse('blog_admin:blog_detail', kwargs={'article_id': self.object.id})
# 表单验证通过,修改一些字段的值
def form_valid(self, form):
if self.request.user:
form.instance.author = self.request.user
from django.contrib.auth.models import Group
# 如果用户在已注册的组中,当发布了一篇文章后,将用户移动到作者的组(id=4)中
if self.request.user in Group.objects.get(id=5).user_set.all():
Group.objects.get(id=5).user_set.remove(self.request.user)
Group.objects.get(id=4).user_set.add(self.request.user)
# 博客创建保留上次创建的记录在表单中
csrftoken = self.request.COOKIES.get('csrftoken', None)
if csrftoken:
# 保存记录到redis
self.redis_db.set('{}:create:article:select:category'.format(csrftoken), form.cleaned_data.get('category').id, ex=43200) # 12小时过期
select_feature = form.cleaned_data.get('feature').id if form.cleaned_data.get('feature') else 0
self.redis_db.set('{}:create:article:select:feature'.format(csrftoken), select_feature, ex=43200)
self.redis_db.set('{}:create:article:select:tags'.format(csrftoken), '_'.join(map(lambda tag: str(tag.id), form.cleaned_data.get('tags'))), ex=43200) # 转为"1_3_5"字符串
return super(BlogCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(BlogCreate, self).get_context_data(**kwargs)
context['status_choices'] = list(map(lambda x: {'status_code': x[0], 'status_value': x[1]}, Article.STATUS_CHOICES))
context['categories'] = Category.objects.all()
context['features'] = Feature.objects.all()
context['tags'] = Tag.objects.all()
context['select_category'] = context['select_feature'] = ''
context['select_tags'] = []
if self.request.path == reverse('blog_admin:blog_create'):
csrftoken = self.request.COOKIES.get('csrftoken', None)
last_select_category = self.redis_db.get('{}:create:article:select:category'.format(csrftoken))
last_select_feature = self.redis_db.get('{}:create:article:select:feature'.format(csrftoken))
last_select_tags = self.redis_db.get('{}:create:article:select:tags'.format(csrftoken))
# print(last_select_tags.split('_'))
if last_select_category and last_select_feature and last_select_tags:
context['select_category'] = int(last_select_category)
context['select_feature'] = int(last_select_feature)
context['select_tags'] = list(int(tag_id) for tag_id in last_select_tags.split('_')) # 只能用int类型
return context
创建表单前端模板
<div class="form-group">
<label for="{{ form.category.id_for_label }}">{{ form.category.label_tag }}</label>
<select class="form-control select2" name="category" id="{{ form.category.id_for_label }}" style="width: 100%">
{% for category in categories %}
<option value="{{ category.id }}" {% if form.category.value == category.id or category.id == select_category %} selected {% endif %}
style="height: 30px">{{ category.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="{{ form.feature.id_for_label }}">{{ form.feature.label_tag }}</label>
<select class="form-control select2" name="feature" id="{{ form.feature.id_for_label }}" style="width: 100%">
<option value="" {% if not form.feature.value %} selected {% endif %} style="height: 30px">---------------</option>
{% for feature in features %}
<option value="{{ feature.id }}" {% if form.feature.value == feature.id or feature.id == select_feature %} selected {% endif %}
style="height: 30px">{{ feature.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="{{ form.tags.id_for_label }}">{{ form.tags.label_tag }}</label>
<select class="select2 select2-hidden-accessible" name="tags" id="{{ form.tags.id_for_label }}" multiple="" data-placeholder="可选择多个标签" aria-hidden="true"
style="width: 100%;">
{% for tag in tags %}
<option value="{{ tag.id }}" {% if tag.id in form.tags.value or tag.id in select_tags %} selected {% endif %}>{{ tag.name }}</option>
{% endfor %}
</select>
</div>
网友评论