【问题标题】:Checking to see if a database duplicate with Null field检查数据库是否与 Null 字段重复
【发布时间】:2011-09-13 14:52:04
【问题描述】:

我正在尝试在添加条目之前检查并查看数据库中是否存在重复条目。这是我目前的模型--

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()

如果未填写 class_date,我将收到 ValueError。如何解决这个问题以及检查重复项时?谢谢。

【问题讨论】:

    标签: django django-models django-views


    【解决方案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()
    ...
    

    【讨论】:

    • 这并不能解决 class_year 有 Null/None 字段的问题。它仍然会为基数为 10() 的无效文字创建 ValueError。还有其他想法吗?
    • 我将 clean 方法更改为如下,现在可以使用:if not self.cleaned_data.get('class_year'):self.cleaned_data['class_year'] = Noneif 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
    

    【讨论】:

      猜你喜欢
      • 2018-09-16
      • 2014-03-24
      • 2014-07-16
      • 2018-11-15
      • 2017-04-21
      • 2018-03-05
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多