python - django:在保存到数据库之前验证多对多关系的计数
问题描述
我有点卡在我的 django 项目中。我想做以下事情:我有两个模型(省略了不必要的部分):
楷模
class UserGroup(models.Model):
max_users = IntegerField()
@property
def user_count(self):
return len(self.user_set.objects.all())
class User(models.Model):
groups = models.ManyToManyField(UserGroup)
def clean(self):
if self.abschnitt.count() > 2:
return ValidationError("only two groups allowed")
形式
class RegisterForm(ModelForm):
class Meta:
model = user
fields = ['usergroup']
widgets = {'usergroup': CheckboxSelectMultiple()}
def clean_usergroup(self):
qs = self.cleaned_data['usergroup']
a = len(qs)
if len(qs) > 2:
raise ValidationError("Your group limit is 2")
return qs
用户组可以定义,通常有 3 到 5 个,每个UserGroup
组有最多可以加入的用户。然而,一个用户可以加入多个群组,但他应该被限制最多加入 2 个群组。
用户可以通过从模型生成的User
模型表单来选择他的组。
我的方法是覆盖clean()
表单的方法和表单的方法clean_groups()
,但我总是遇到问题,当重新加载表单时出现异常:
ValueError: "<User: User object (None)>" needs to have a value for field "id" before this many-to-many relationship can be used.
我知道这是有道理的,因为没有可以检查的已保存 m2m 关系,因此我宁愿尝试在保存表单之前对其进行验证,但不幸的是,这不起作用。
这是呈现表单的视图:
def index(request):
if request.method == 'POST':
f = RegisterForm(request.POST)
if f.is_valid(): # <- exception occurs here or one line below
new_user = f.save(commit=False)
# adding some metadata to the object, not relevant for m2m, but commit = False is required for that
return render(request, 'registration/preregister_done.html')
else:
f = RegisterForm()
return render(request, 'register/index.html', {'form': f})
是否有可能验证用户不检查超过 2 个组而不将其存储在数据库中?
解决方案
我找到了一个可行的解决方案:
经过一点调试,我发现在调用f.is_valid()
模型验证时也会运行。我为pk添加了一个小验证。我改变了这样的模型验证:
def clean(self):
if self.pk: # <-- this was missing
if self.usergroup.count() > 2:
return ValidationError("only two groups allowed")
现在表单验证使用 f.is_valid() 可以顺利运行。
推荐阅读
- javascript - reactjs不能将道具传递给纬度和经度(谷歌地图)
- c# - C# HttpWebRequest - 为什么不是所有收到的 cookie 都在后续请求中发回?
- postgresql - 连接到通过 docker 在我的 ubuntu 服务器上运行的 postgres 实例
- javascript - [Vue 警告]:v-on 处理程序中的错误:“TypeError:fs.existsSync 不是函数”
- pythonanywhere - 这就是我必须为自定义域做的所有事情吗?
- mysql - 我想检查上面的值是否重复。我该怎么做?
- microsoft-translator - Microsoft 翻译器更改有 html 跨度的短语
- python - 如何显示类别名称和描述?
- c# - 错误!'对象不能从 DBNull 转换为其他类型。' C# 使用方法 sum()
- python - 如何在 Dask 任务执行之间保留一些 Python 对象状态?