python - Django 传递用户 ID 来过滤模型
问题描述
我试图过滤模型中的对象,以避免人们将事件放在重叠的日历中。我发现以下链接有助于(Django 表单字段清理以检查输入的日期是否在存储范围内)。它给我留下了另一个问题,它阻止任何其他用户同时进行活动。
我的问题是,我可以通过用户 ID 号来过滤查询集吗?如果我手动输入我的用户 ID 号,它会起作用吗?
下面是我最后一次尝试的代码?
模型.py
from django.db import models
from django.contrib.auth.models import User
class Event(models.Model):
manage = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
title = models.CharField(max_length=200, default='free')
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
def __str__(self):
return self.title + " - " + str(self.start_time) + " - " + str(self.end_time)
表格.py
from django import forms
from django.forms import ModelForm, DateInput
from calendar_app.models import Event
from django.contrib.auth.models import User
class EventForm(ModelForm):
class Meta:
model = Event
# datetime-local is a HTML5 input type, format to make date time show on fields
widgets = {
'start_time': DateInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
'end_time': DateInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
}
fields = ['title','description','start_time','end_time']
def __init__(self, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
# input_formats parses HTML5 datetime-local input to datetime field
self.fields['start_time'].input_formats = ('%Y-%m-%dT%H:%M',)
self.fields['end_time'].input_formats = ('%Y-%m-%dT%H:%M',)
def clean(self):
form_start_time = self.cleaned_data.get('start_time')
form_end_time = self.cleaned_data.get('end_time')
form_manage = self.cleaned_data.get('manage')
between = Event.objects.filter(manage=form_manage, start_time__gte=form_start_time, end_time__lte=form_end_time)
if between:
raise forms.ValidationError('Already Calendar entry for this time')
super(EventForm,self).clean()
视图.py
def event(request, event_id=None):
instance = Event()
if event_id:
instance = get_object_or_404(Event, pk=event_id)
else:
instance = Event()
form = EventForm(request.POST or None, instance=instance)
if request.POST and form.is_valid():
instance.manage = request.user
form.save()
return HttpResponseRedirect(reverse('calendar_app:calendar'))
return render(request, 'event.html', {'form': form})
解决方案
您可以使用包装在表单manage_id
中的对象:Event
class EventForm(ModelForm):
# …
def clean(self):
form_start_time = self.cleaned_data.get('start_time')
form_end_time = self.cleaned_data.get('end_time')
between = Event.objects.filter(
manage_id=self.instance.manage_id,
start_time__gte=form_start_time,
end_time__lte=form_end_time
)
if between.exists():
raise forms.ValidationError('Already Calendar entry for this time')
super().clean()
当然,这仅在Event
alreadh 有 a时才有效manage_id
,但这不是问题,因为我们可以在必要时添加用户的主键。manage_id
在中过滤get_object_or_404
以防止用户编辑彼此的事件可能也更安全:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
@login_required
def event(request, event_id=None):
instance = Event()
if event_id:
instance = get_object_or_404(Event, pk=event_id, manage_id=request.user.pk)
else:
instance = Event(manage_id=request.user.pk)
if request.method == 'POST':
form = EventForm(request.POST, request.FILES, instance=instance)
if form.is_valid():
form.save()
return redirect('calendar_app:calendar')
else:
form = EventForm(instance=instance)
return render(request, 'event.html', {'form': form})
注意:您可以使用
@login_required
装饰器 [Django-doc]将视图限制为经过身份验证的用户的视图 。
注意:通常使用
settings.AUTH_USER_MODEL
[Django-doc]引用用户模型比直接使用User
模型 [Django-doc]更好。有关更多信息,您可以查看文档的引用User
模型部分。
推荐阅读
- python - 如何在python中获取str中的值(不是数组/列表格式)
- scala - Scala 未来返回类型
- c++ - 多个对象的异常处理
- linux - linux内核驱动程序-在irq和工作线程之间同步
- angular - 即使添加到构造函数Angular中,属性也不存在错误
- python - 根据一列的值创建多列-Python,Pandas
- algorithm - 了解二进制搜索背后的直觉,以查找较小(最左边的 occ。)和较大(最右边的 occ。)元素(有重复)的计数
- node.js - 全局安装的节点模块
- node.js - split.EOL 在 Windows 中给出不同的结果
- python - 如何使用 Python 从网站下载交互式地图?