【发布时间】:2019-04-09 16:04:06
【问题描述】:
我的代码中存在两个字段条目唯一性检查的问题。
我用unique_together 定义了一个模型来检查每个用户的字段记录的唯一性,但它接受该用户添加的重复条目。
model.py
from django.db import models
from django.contrib.auth.models import User
class UserItem(models.Model):
definer = models.ForeignKey(User, on_delete=models.CASCADE)
item_name = models.CharField(max_length=50)
.
.
class Meta:
unique_together = ("definer", "item_name")
views.py
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class RecordCreateView(LoginRequiredMixin, CreateView):
model = UserItem
template_name = 'item_new.html'
#excluding "definer" field and inserting its value by form_valid
fields = ['item_name', . . .]
def form_valid(self, form):
form.instance.definer = self.request.user
return super().form_valid(form)
我希望警告并阻止用户使用之前添加的相同“item_name”添加新记录,但它接受它们(没有警告)。
当我用其他字段替换“定义器”时,它可以正常工作并警告重复记录。此外,当管理员添加记录时,它会起作用并且会出现预期的警告。
我想,这个问题是因为在“unique_together = ("definer", "item_name")" 完成其角色之后,经过身份验证的用户被 "def form_valid" 插入为 "definer"。另一方面,当“定义器”为空时进行唯一性检查。
我应该怎么做才能解决这个问题?
编辑:添加完整模型
```` Full Model in model.py
class UserItem(models.Model):
item_type = models.CharField(max_length=12, verbose_name='Item type')
item_name = models.CharField(max_length=50)
bound = models.CharField(null=True, blank=True, default=None, max_length=4, verbose_name='Bound')
price = models.FloatField(default=0)
maximum_use = models.FloatField(default=0, verbose_name='Maximum use (%)’)
matterial = models.FloatField(null=True, blank=True, default=None, verbose_name='matterial (%)')
energy = models.FloatField(null=True, blank=True, default=None, verbose_name='energy (kcal/k)')
definer = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return "{}, name: {}, definer: {}".format(self.item_type, self.item_name, self.definer,)
def get_absolute_url(self):
return reverse('profile')
class Meta:
unique_together = ("definer", "item_name")
````
```` views.py after @Pedro suggestion to edit
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
class RecordCreateView(LoginRequiredMixin, CreateView):
model = UserItem
template_name = 'item_new.html'
fields = ['item_name', 'matterial', 'energy',]
def get_success_url(self):
return reverse('profile')
def form_valid(self, form):
user_item = form.save(commit=False)
user_item.definer = self.request.user
user_item.item_type = 'required'
user_item.bound = 'min'
try:
user_item.save()
except IntegrityError:
form.add_error('item_name', 'Item name is repeated')
return self.form_invalid(form)
return HttpResponseRedirect(self.get_success_url())
````
【问题讨论】:
-
如果你已经用
makemigrations和migrate将约束迁移到数据库中(如果可以,检查约束是否存在于数据库中),约束违反是不可能的。可以创建违反约束的模型实例,但无法保存它们。因此,请进一步挖掘到底发生了什么。约束不是问题。 -
我不确定您在
form.instance.definer = self.request.user这一行中在做什么,如果您使用的是创建视图,则您没有实例。你能解释一下吗? -
@Pedro 我是一个初学者,在这个应用程序中没有 form.py 文件,我从书中的类似代码中得到了这个模式(包括实例)(Django for Beginners, Learn Web Development with Django 2.0 ) 和网页。这是个问题吗?
标签: python django django-models django-orm unique-constraint