如何在与用户关联的实例中对 Django 字段应用约束

how to apply constraints on Django field within the instances associated with the user

我正在制作一个待办事项应用程序来练习,我想要实现的功能是,当用户创建任务时,只有时间字段对于他的所有任务来说应该是唯一的,我已经完成了(unique=True ) 在模型的时间字段中,但这使得它在整个数据库中都是唯一的,但我希望它只在与用户相关的任务中是唯一的。 视图如下:

@login_required(login_url='login')
def home(request):
    tasks = Task.objects.filter(name__username=request.user.username)

    form = TaskForm()
    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.name = request.user
            obj.save()
            return redirect('home')
        else:
            print(request.POST)
            print(request.user.username)
            messages.warning(request, 'Invalid Data!')
            return redirect('home')

    context = {'tasks' : tasks}
    return render(request, 'task/home.html', context)

任务模型:

class Task(models.Model):
    choices = (
        ('Completed', 'Completed'),
        ('In Complete', 'In Complete'),
    )
    name = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    task = models.CharField(max_length=200, null=False, blank=False)
    time = models.TimeField(auto_now_add=False, blank=True)
    status = models.CharField(max_length=200, choices=choices, null=True, blank=False)
    
    def __str__(self):
        return self.task
    
    def get_task_author_profile(self):
        return reverse('profile')

如您所见,我想显示登录用户添加的任务。

表格是:

class TaskForm(ModelForm):
    class Meta:
        model = Task
        fields = '__all__'
        exclude = ['name']

我上面说的功能,我尝试通过view来实现:

@login_required(login_url='login')
def home(request):
    tasks = Task.objects.filter(name__username=request.user.username)
    time = []
    for task in tasks:
        time.append(task['time'])
    form = TaskForm()
    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid() and form.cleaned_data['time'] != time:
            obj = form.save(commit=False)
            obj.name = request.user
            obj.save()
            return redirect('home')
        else:
            print(request.POST)
            print(request.user.username)
            messages.warning(request, 'Invalid Data!')
            return redirect('home')

    context = {'tasks' : tasks}
    return render(request, 'task/home.html', context)

但是出现错误:TypeError: 'Task' object is not subscriptable
我知道这不对,但是我怎样才能实现它,Django 有什么可以提供这样的功能吗?

问题出在这里:

for task in tasks:
    time.append(task['time'])  #<--

这里如果要使用访问时间,需要使用task.time,因为task是一个对象

还需要修复现有代码中的另一件事才能使其正常工作,因为 time 是一个列表:

if form.is_valid() and form.cleaned_data['time'] in time:  
#                                                ^^^

顺便说一句,你不需要让它变得那么复杂,你可以从模型中添加数据库级别的约束,使特定用户的时间唯一。此外,为此使用 DateTime 字段。您可以为此使用 unique_togather

class Task(models.Model):
    choices = (
        ('Completed', 'Completed'),
        ('In Complete', 'In Complete'),
    )
    name = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    task = models.CharField(max_length=200, null=False, blank=False)
    time = models.DateTimeField(auto_now_add=False, blank=True)
    status = models.CharField(max_length=200, choices=choices, null=True, blank=False)
    
    class Meta:
        unique_togather = ['name', 'time']