<p>以一种完全通用的方式。在模型中有以下两个助手fn:</p>
<pre><code>def getField(self,fieldName):
# return the actual field (not the db representation of the field)
try:
return self._meta.get_field_by_name(fieldName)[0]
except models.fields.FieldDoesNotExist:
return None
</code></pre>
<p>以及</p>
<pre><code>def getUniqueTogether(self):
# returns the set of fields (their names) that must be unique_together
# otherwise returns None
unique_together = self._meta.unique_together
for field_set in unique_together:
return field_set
return None
</code></pre>
<p>在表格中有以下fn:</p>
<pre><code>def clean(self):
cleaned_data = self.cleaned_data
instance = self.instance
# work out which fields are unique_together
unique_filter = {}
unique_fields = instance.getUniqueTogether()
if unique_fields:
for unique_field in unique_fields:
field = instance.getField(unique_field)
if field.editable:
# this field shows up in the form,
# so get the value from the form
unique_filter[unique_field] = cleaned_data[unique_field]
else:
# this field is excluded from the form,
# so get the value from the model
unique_filter[unique_field] = getattr(instance,unique_field)
# try to find if any models already exist in the db;
# I find all models and then exlude those matching the current model.
existing_instances = type(instance).objects.filter(**unique_filter).exclude(pk=instance.pk)
if existing_instances:
# if we've gotten to this point,
# then there is a pre-existing model matching the unique filter
# so record the relevant errors
for unique_field in unique_fields:
self.errors[unique_field] = "This value must be unique."
</code></pre>