#django #django-models #django-views
#django #django-модели #django-просмотры
Вопрос:
Я пытаюсь проверить, есть ли дублирующаяся запись в базе данных, прежде чем добавлять запись. Вот мои текущие модели —
class Education(models.Model):
school = models.CharField(max_length=100)
class_year = models.IntegerField(max_length=4, blank=True, null=True, choices=YEAR)
degree = models.CharField(max_length=100, blank=True, null=True)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
employments = models.ManyToManyField(Employment)
В форме пользователь должен ввести школу. Год выпуска и степень необязательны. Чтобы проверить наличие дублирующихся записей, прямо сейчас у меня есть —
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
try:
school_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except (Education.DoesNotExist):
school_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
school_object.save()
profile.educations.add(school_object)
profile.save()
Я получаю ошибку ValueError, если class_date не заполнен. Как это исправить, а также при проверке на наличие дубликатов? Спасибо.
Ответ №1:
Во-первых, если у вас нет веской причины, вам действительно не следует обращаться к переменным post без отправки их через форму.
from django import forms
class MyForm(forms.form):
school = forms.CharField()
degree = forms.CharField(required=False)
class_year = forms.CharField(required=False)
def clean(self):
if not self.cleaned_data.has_key('degree'):
self.cleaned_data['degree'] = None
if not self.cleaned_data.has_key('class_year'):
self.cleaned_data['class_year'] = None
return self.cleaned_data
Затем, когда вы обрабатываете представление:
...
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
try:
# NOTE that the objects.get method will raise MultipleObjectsReturned if the
# database has more than one object that matches the query
my_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except Education.DoesNotExist:
my_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
else:
form = MyForm()
...
Комментарии:
1. Это не устраняет проблему наличия поля Null / None для class_year. Это все равно создаст ValueError для недопустимого литерала с базой 10(). Есть еще идеи?
2.Я изменил метод clean на следующий, который теперь работает:
if not self.cleaned_data.get('class_year'):
self.cleaned_data['class_year'] = None
if not self.cleaned_data.get('degree'):
self.cleaned_data['degree'] = ''
return self.cleaned_data
Ответ №2:
В представлениях:
if 'Add School' in request.POST.values():
form = EducationForm(request.POST)
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
try:
school_object = Education.objects.get(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
except (Education.DoesNotExist, ValueError):
school_object = Education(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
school_object.save()
profile.educations.add(school_object)
profile.save()
return redirect('edit_education')
Или, используя get_or_create
для упрощения:
if 'Add School' in request.POST.values():
form = EducationForm(request.POST)
if form.is_valid() and request.POST['school']:
school = form.cleaned_data['school']
school_object, created = Education.objects.get_or_create(school=form.cleaned_data['school'],
class_year=form.cleaned_data['class_year'],
degree = form.cleaned_data['degree'])
if created:
profile.educations.add(school_object)
profile.save()
return redirect('edit_education')
В формах:
YEAR = ([(x, x) for x in range(1970,2015)])
YEAR.append((0,'Select Year'))
YEAR.reverse()
class EducationForm(forms.Form):
school = forms.CharField()
class_year = forms.ChoiceField(choices=YEAR, required=False)
degree = forms.CharField(required=False)
def clean(self):
if not self.cleaned_data.get('class_year'):
self.cleaned_data['class_year'] = None
if not self.cleaned_data.get('degree'):
self.cleaned_data['degree'] = ''
return self.cleaned_data