我有以下Model
s:
class Book(models.Model):
name = models.CharField(max_length=128)
isbn = models.CharField(max_length=13, unique=True)
available = models.BooleanField(default=True)
class Borrow(models.Model):
date = models.DateTimeField(auto_now_add=True)
book = models.ForeignKey(Book)
以及以下ModelForm
:
class CreateBorrowForm(forms.ModelForm):
class Meta:
model = Borrow
fields = ['book']
def clean_book(self):
book = self.cleaned_data['book']
try:
return Book.objects.get(id=book, available=True)
except Book.DoesNotExist:
raise ValidationError('Book does not exist or it is unavailable')
我想要一个期望Book
模型的isbn
字段而不是id
的表单。由于isbn
字段是唯一的,因此它确实有意义。在clean_book
方法中,我需要做一点更改,以获得以下行:
return Book.objects.get(isbn=book, available=True)
问题是,我找不到强制表单使用不同的唯一标识符的方法。在我的特定情况下,这是为了避免对数字ID进行暴力枚举所必需的。
您需要为此使用自定义字段,并覆盖save()
方法而不是clean__field()
:
class CreateBorrowForm(forms.ModelForm):
book_isbn = forms.CharField()
class Meta:
model = Borrow
fields = ['book_isbn']
def save(self, commit=True):
instance = super().save(commit=False)
book_isbn = self.cleaned_data['book_isbn']
try:
book = Book.objects.get(isbn=book_isbn, available=True)
instance.book = book
except Book.DoesNotExist:
raise ValidationError('Book does not exist or it is unavailable')
if commit:
instance.save()
return instance