【问题标题】:Django models avoid duplicatesDjango 模型避免重复
【发布时间】:2011-03-04 10:29:40
【问题描述】:

在模型中:

class Getdata(models.Model):
    title = models.CharField(max_length=255)
    state = models.CharField(max_length=2, choices=STATE, default="0")
    name = models.ForeignKey(School)
    created_by = models.ForeignKey(profile)

    def __unicode__(self):
        return self.id()

在模板中:

<form>
    <input type="submit" value="save the data" />
</form> 

如果用户点击保存按钮,上面的数据保存在表格中,如何避免重复,即如果用户再次点击同一个提交按钮,不应该有相同值的另一个条目。还是必须在视图中处理?

【问题讨论】:

    标签: python django django-models django-templates django-views


    【解决方案1】:

    我认为注入 Jquery/JS 代码来隐藏保存按钮是个好主意。

    创建一个如下所示的 custom_validate.js 文件并将其放在目录 static(静态文件目录)中

    if (!$) {
        $ = django.jQuery;
    }
    
    $( document ).ready(function() {
        $("[name=_save]").click(function() {
           $("[name=_save]").css("visibility", "hidden");
        });
    });
    

    在 admin.py 中,添加以下代码。

    class CustomDataForm(forms.ModelForm):
    
        class Meta:
            model = GetData
    
    class GetDataAdmin(admin.ModelAdmin):
        # ....
        .....
        form = CustomDataForm
    
        class Media:
            js = ('/static/custom_validate.js', )
    

    【讨论】:

      【解决方案2】:

      unique_together 也建议是最好的方法,但如果这不适合您的需要,您可以在表单的 clean 方法中处理它。例如

      def clean(self):
         try:
            Getdata.objects.get(title=self.cleaned_data['title'], 
                                state=self.cleaned_data['state'],
                                name=self.cleaned_data['name'],
                                created_by=self.cleaned_data['created_by'] )
            #if we get this far, we have an exact match for this form's data
            raise forms.ValidationError("Exists already!")
         except Getdata.DoesNotExist:
            #because we didn't get a match
            pass
      
         return self.cleaned_data
      

      【讨论】:

      • 我还看到,对于多次提交的情况,人们使用 JavaScript 在单击提交按钮并提交表单时禁用它。最好的解决方案可能是所有这些的组合。
      • 在我的代码中我暂时做了同样的事情..但这与其他人不一致..所以我必须知道这一点..下次我可以使用正确的代码而不是黑客..
      【解决方案3】:

      如果单个字段需要唯一,则只需添加unique=True

      class Getdata(models.Model):
          title = models.CharField(max_length=255, unique=True)
          state = models.CharField(max_length=2, choices=STATE, default="0")
          name = models.ForeignKey(School)
          created_by = models.ForeignKey(profile)
      

      如果希望字段组合唯一,则需要unique_together

      class Getdata(models.Model):
          title = models.CharField(max_length=255)
          state = models.CharField(max_length=2, choices=STATE, default="0")
          name = models.ForeignKey(School)
          created_by = models.ForeignKey(profile)
          class Meta:
              unique_together = ["title", "state", "name"]
      

      【讨论】:

      • 另外,当 getdata 在视图中调用第二个示例时,默认情况下这将返回“title”、“state”和“name”是吗?
      • 当您在视图中引用 Getdata 对象时,您将获得一个 Getdata 对象及其所有字段。
      猜你喜欢
      • 2021-09-08
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 2017-08-05
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多