在我的模型中,我想使用验证器来分析文件的内容,我想不通的是如何访问文件的内容来解析它,因为文件尚未保存(这很好) 当验证器正在运行时。
我不明白如何将value传递给验证器的数据获取到文件中(我假设我应该使用tempfile),以便我可以打开它并评估数据。
这是一个简化的示例,在我的真实代码中,我想打开文件并使用 csv 对其进行评估。
在 Models.py 中
class ValidateFile(object):
....
def __call__(self, value):
# value is the fieldfile object but its not saved
# I believe I need to do something like:
temp_file = tempfile.TemporaryFile()
temp_file.write(value.read())
# Check the data in temp_file
....
class MyItems(models.Model):
data = models.FileField(upload_to=get_upload_path,
validators=[FileExtensionValidator(allowed_extensions=['cv']),
ValidateFile()])
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助!
我试图将所有与业务逻辑相关的验证移动到模型中,而不是将它们留在表单中。但在这里我遇到了一个棘手的情况,为此我想咨询 SO 社区。
在我的 SignupForm(一个模型表单)中,我有以下特定于字段的验证,以确保输入的电子邮件不存在。
def clean_email(self):
email = self.cleaned_data['email']
if ExtendedUser.objects.filter(email=email).exists():
raise ValidationError('This email address already exists.')
return email
Run Code Online (Sandbox Code Playgroud)
如果我要将此验证移动到模型中,根据官方文档,我会将其放入clean()相应的模型中ExtendedUser。但该文档还提到了以下内容:
Model.clean() 引发的任何 ValidationError 异常都将存储在特殊键错误字典键 NON_FIELD_ERRORS 中,该键用于与整个模型而非特定字段相关的错误
这意味着,对于clean(),我无法将由此引发的错误与特定字段相关联。我想知道模型是否提供类似于 forms' 的东西clean_<fieldname>()。如果没有,你会把这个验证逻辑放在哪里,为什么?
以下是我的模型定义
class ProfessionalQualification(Log_Active_Owned_Model_Mixin):
PROF_TEACHER = 1
PROF_ENGINEER = 2
PROF_DOCTOR = 4
PROF_PROFESSOR = 8
PROF_MANAGER = 16
PROF_CLERK = 32
PROF_SALESMAN = 64
PROF_BUSINESSMAN= 128
PROF_OTHER = 129
VALID_PROFESSIONS = (
(PROF_TEACHER, "Teacher" ),
(PROF_ENGINEER, "Engineer" ),
(PROF_DOCTOR, "Doctor" ),
(PROF_PROFESSOR, "Professor" ),
(PROF_MANAGER, "Manager" ),
(PROF_CLERK, "Clerk" ),
(PROF_SALESMAN, "Salesman" ),
(PROF_BUSINESSMAN, "Businessman"),
(PROF_OTHER, "Other" )
)
profession_type = IntegerField(choices=VALID_PROFESSIONS, null=False, blank=False)
profession_type_name = CharField(max_length=60, null=True, blank=True)
institue = CharField(max_length=160, null=False, blank=False)
address = ForeignKey(to=City, null=False)
year_start = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用__init__参数将变量传递给 ModelForm clean 方法,但到目前为止还没有成功 - 我查看了 StackOverflow 上的各种帖子,但似乎没有一个有帮助。
我的代码如下:
forms.py
class property_booking_form(forms.ModelForm):
check_in_date = forms.DateField(widget=SelectDateWidget)
check_out_date = forms.DateField(widget=SelectDateWidget)
class Meta:
model = Properties_bookings
fields = ['check_in_date', 'check_out_date']
def __init__(self, property_id):
self.property_id = property_id
super(property_booking_form, self).__init__(self, property_id)
def clean(self):
check_in_date = self.cleaned_data.get('check_in_date')
check_out_date = self.cleaned_data.get('check_out_date')
property_min_nights = Properties.objects.get(id=self.property_id).property_minimum_nights
...
views.py
def view(request):
...
if request.method == 'POST':
booking_form = property_booking_form(request.POST, property_id=property_id)
if booking_form.is_valid():
...
else:
booking_form = property_booking_form(property_id=property_id)
return render(...)
Run Code Online (Sandbox Code Playgroud)
这会引发以下错误:“property_booking_form”对象没有属性“get”
根据错误描述,这似乎与小部件有关:
异常位置:
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py in value_from_datadict, line 1058
Run Code Online (Sandbox Code Playgroud)
该表单在没有覆盖的情况下工作正常 …
我正在使用Django 2.0并试图允许用户在django ModelForm中输入他们网站的链接.我想让我的URLField验证网址,即使它们没有方案前缀.
我已经阅读了这个解决方案:django urlfield http前缀.我想知道是否有办法实现这一点,而无需在RegexValidator中编写我自己的自定义正则表达式.重复URLValidator中内置的所有正则表达式逻辑似乎不是一个非常干的解决方案.
我想做类似下面的事情:
website = models.CharField(max_length=400, blank=True, null=True, validators=[URLValidator(schemes=['', 'http', 'https', 'ftp', 'ftps'])])
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为URLValidator的调用方法验证了给定的方案.
def __call__(self, value):
# Check first if the scheme is valid
scheme = value.split('://')[0].lower()
if scheme not in self.schemes:
raise ValidationError(self.message, code=self.code)
Run Code Online (Sandbox Code Playgroud)
将空字符串添加到方案列表不起作用,因为以这种方式拆分URL会返回整个URL(因为用户通常不包括://如果该用户不包含方案前缀).
现在,我可以继承URLField并覆盖整个调用方法,以便改变它处理方案的方式,但是调用方法包括所有的正则表达式,所以这似乎不再仅仅是将URLField正则表达式复制到我自己的RegexValidator中.
是否有更清洁或更"Djangonic"的方式来实现这一目标?
我已经尝试了在互联网上可以找到的所有内容,但似乎没有任何效果,所以想知道以前的许多答案是否适用于旧版本。我使用的是 Django 2.2.9。
#models.py
class ParentModel(models.Model):
title = models.CharField()
class ChildModel(models.Model):
parent = models.ForeignKey(
ParentModel,
on_delete=models.CASCADE,
related_name='parent'
)
Run Code Online (Sandbox Code Playgroud)
# admin.py
@admin.register(ParentModel)
class ParentModelAdmin(admin.ModelAdmin):
model = ParentModel
def get_queryset(self, request):
return ParentModel.objects.get_complete_queryset()
class ChildModelForm(forms.Form):
def __init__(self, u, *args, **kwargs):
super(ChildModelForm, self).__init__(*args, **kwargs)
self.fields['parent'].queryset = ParentModel.objects.get_complete_queryset()
class Meta:
model = ChildModel
fields = '__all__'
@admin.register(ChildModel)
class ChildModelAdmin(admin.ModelAdmin):
model = ChildModel
form = ChildModelForm
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "parent":
kwargs["queryset"] = ParentModel.objects.get_complete_queryset()
return super().formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)
get_complete_queryset我调用了一个经理查询,ParentModel …
我的数据库中有客户记录列表。每年,我们都会为每个客户生成一个工作订单。然后,对于每个工单记录,用户应该能够创建特定于工单的注释。然而,并不是所有的工单都需要注释,只是一些。
现在,我不能简单地note向工作订单添加一个字段,因为有时,我们甚至需要在生成工作订单之前创建注释。有时,此注释特定于 2-3 年内不会发生的工作订单。因此,注释和工单必须是独立的,尽管当它们都存在时它们会“找到”彼此。
好的,情况就是这样。我希望用户能够填写一个非常简单的note表单,其中有两个字段:noteYear和note。因此,他们所做的就是选择一年,然后写下笔记。关键是用户不应该能够为同一个客户在同一年创建两个笔记。
我试图通过确保该客户没有该年的注释来验证该注释。我假设这将通过is_valid表单中的自定义方法来实现,但我不知道如何去做。
这是我到目前为止所尝试的(请注意,我知道这是错误的,它不起作用,但这是我迄今为止的尝试):
请注意,这systemID是我的客户记录
我的型号:
class su_note(models.Model):
YEAR_CHOICES = (
('2013', 2013),
('2014', 2014),
('2015', 2015),
('2016', 2016),
('2017', 2017),
('2018', 2018),
('2019', 2019),
('2020', 2020),
('2021', 2021),
('2022', 2022),
('2023', 2023),
)
noteYear = models.CharField(choices = YEAR_CHOICES, max_length = 4, verbose_name = 'Relevant Year')
systemID = models.ForeignKey(System, verbose_name = 'System ID')
note = models.TextField(verbose_name = "Note")
def __unicode__(self):
return u'%s | %s | …Run Code Online (Sandbox Code Playgroud) 我正在尝试验证 MyModel 和 Item 的变量 foo 是否相同,然后再将其添加为 m2m。如果不是,我想在管理员中提出 ValidationError 。
模型.py
class Item(models.Model):
foo = models.CharField(max_length=200)
class MyModel(models.Model):
foo = models.CharField(max_length=200)
items = models.ManyToManyField(Item)
Run Code Online (Sandbox Code Playgroud)
信号.py
@receiver(m2m_changed, sender=MyModel.items.through)
def my_validator(sender, instance, action, pk_set, **kwargs):
if action == 'pre_add':
if Item.objects.filter(id__in=pk_set, foo=instance.foo).count() != len(pk_set):
raise ValidationError({'items': ["Foo doesn't match"]})
Run Code Online (Sandbox Code Playgroud)
有没有办法让 ValidationError 在管理员中正确显示,而不是显示为 500 错误。
我无法想出一个解决方案来使用 MyModel 的 clean 方法来验证 foo 的相同值。任何建议表示赞赏。
从 django 默认验证器返回的所有错误消息均以点 (.) 结尾。无论如何,是否可以从全局所有消息中删除最后一个点。
或者,如果有人帮助我找到一种方法来捕获这些错误返回函数,我可以修剪最后一个点(如果存在于该部分)。
错误消息示例。
{
"email": [
"This field may not be blank."
]
}
{
"email": [
"Enter a valid email address."
]
}
Run Code Online (Sandbox Code Playgroud) django django-models django-forms django-validation django-rest-framework
我想以不同的方式验证用户提交的数据,无论用户是添加新对象还是更改现有对象。如果对象已经存在(如果它存在于数据库中,则正在添加),除了 id 之外,没有模型的属性可以在数据库上检查。在其他方法中,例如save_model,会传递一个add参数,因此您可以检查它,但在modelform.clean中没有这样的参数。如何在 modelform.clean 中进行验证?
MyModelForm(forms.ModelForm):
def clean(self):
if add :
validation_A()
else:
validantion_B()
Run Code Online (Sandbox Code Playgroud)