flavour
является закрытым. Хотя вы читаете его из общедоступного метода, вы назначаете его частному полю и, скорее всего, не объявляете его в этом классе.
Вы можете настроить вкус protected
в родительском классе или определить для него сеттер
. В конечном итоге ваш код на самом деле не имеет смысла. Даже если бы он скомпилировался, это было бы более или менее: flavour = flavour
. Возможно, вам стоит пересмотреть то, что вы пытаетесь сделать немного
. Мне кажется, вам может понадобиться более пристальное понимание Java и объектно-ориентированного программирования.
http: // docs.oracle.com/javase/tutorial/java/concepts/
Вы должны начать здесь.
Мне удалось исправить это, не изменяя представление, добавив в мою форму чистый метод:
class SolutionForm(forms.ModelForm):
class Meta:
model = Solution
exclude = ['problem']
def clean(self):
cleaned_data = self.cleaned_data
try:
Solution.objects.get(name=cleaned_data['name'], problem=self.problem)
except Solution.DoesNotExist:
pass
else:
raise ValidationError('Solution with this Name already exists for this problem')
# Always return cleaned_data
return cleaned_data
Единственное, что мне нужно сделать сейчас в представлении, - добавить свойство проблемы к перед выполнением is_valid
.
решение от @sttwister является правильным, но может быть упрощено.
class SolutionForm(forms.ModelForm):
class Meta:
model = Solution
exclude = ['problem']
def clean(self):
cleaned_data = self.cleaned_data
if Solution.objects.filter(name=cleaned_data['name'],
problem=self.problem).exists():
raise ValidationError(
'Solution with this Name already exists for this problem')
# Always return cleaned_data
return cleaned_data
В качестве бонуса вы не возвращаете объект в случае дублирования, а только проверяете, существует ли он в базе данных, экономя немного бит исполнений.
Как говорит Феликс, ModelForms должны проверять ограничение unique_together
в их проверке.
Однако в вашем случае вы фактически исключаете один элемент этого ограничения из вашей формы. Я предполагаю, что это ваша проблема - как форма будет проверять ограничение, если половина его даже не на форме?
Вам нужно будет сделать что-то вроде этого:
def your_view(request):
if request.method == 'GET':
form = SolutionForm()
elif request.method == 'POST':
problem = ... # logic to find the problem instance
solution = Solution(problem=problem) # or solution.problem = problem
form = SolutionForm(request.POST, instance=solution)
# the form will validate because the problem has been provided on solution instance
if form.is_valid():
solution = form.save()
# redirect or return other response
# show the form
unique_together
, возможно, потому, что проблема упоминается в свойстве exclude
, хотя у нее есть действительный экземпляр
– sttwister
28 January 2010 в 17:06
Я решил эту же проблему, переопределив метод validate_unique()
ModelForm:
def validate_unique(self):
exclude = self._get_validation_exclusions()
exclude.remove('problem') # allow checking against the missing attribute
try:
self.instance.validate_unique(exclude=exclude)
except ValidationError, e:
self._update_errors(e.message_dict)
Теперь я всегда убеждаюсь, что атрибут, не предоставленный в форме, все еще доступен, например. instance=Solution(problem=some_problem)
в инициализаторе.
Если вы хотите, чтобы сообщение об ошибке было связано с полем name
(и появлялось рядом с ним):
def clean(self):
cleaned_data = super().clean()
name_field = 'name'
name = cleaned_data.get(name_field)
if name:
if Solution.objects.filter(name=name, problem=self.problem).exists():
cleaned_data.pop(name_field) # is also done by add_error
self.add_error(name_field, _('There is already a solution with this name.'))
return cleaned_data
С помощью ответа Ярмо следующее выглядит хорошо для меня (в Django 1.3), но, возможно, я сломал какой-то угловой случай (есть много билетов, окружающих _get_validation_exclusions
):
class SolutionForm(forms.ModelForm):
class Meta:
model = Solution
exclude = ['problem']
def _get_validation_exclusions(self):
exclude = super(SolutionForm, self)._get_validation_exclusions()
exclude.remove('problem')
return exclude
Я не уверен, но это похоже на ошибку Django для меня ... но мне пришлось бы оглянуться на ранее сообщенные проблемы.
Изменить : Я говорил слишком рано. Возможно, то, что я написал выше, будет работать в некоторых ситуациях, но не в моем; Я в конечном итоге использовал ответ Джармо.