Проверка дублирования базы данных с нулевым полем

Я пытаюсь проверить и посмотреть, есть ли повторяющаяся запись в базе данных, прежде чем добавлять запись. Вот мои текущие модели -

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 не заполнен. Как это исправить, а также при проверке дубликатов? Спасибо.


person David542    schedule 13.06.2011    source источник


Ответы (2)


Во-первых, если у вас нет серьезной причины, вам действительно не следует обращаться к переменным сообщения, не отправляя их через форму.

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()
...
person Ted    schedule 13.06.2011
comment
Это не решает проблему наличия поля Null/None для class_year. Он по-прежнему будет создавать ValueError для недопустимого литерала с основанием 10(). Любые другие идеи? - person David542; 13.06.2011
comment
Я изменил метод очистки следующим образом, который теперь работает: 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 - person David542; 13.06.2011

В представлениях:

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
person David542    schedule 13.06.2011