django "duplicate key value violates unique constraint"主键

标签 django postgresql forms

我写的表格中出现了一些非常奇怪的错误。

使用: Postgres 8.4 Ubuntu 10.04 奥顿2.6 Django 1.2.4

基本上我有一个收集姓名和电子邮件地址的表格。但我需要在另外两个表中制作虚拟行,以便我们可以跟踪它们。以下型号。

from django.db import models
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.contrib.sites.models import Site


# Create your models here.

class company(models.Model):
    company = models.CharField(max_length=100)
    address = models.CharField(max_length=300)
    street = models.CharField(max_length=200)
    suburb = models.CharField(max_length=100)
    phone_number = models.CharField(max_length=15)
    contact_person = models.CharField(max_length=50,null=True)
    email = models.EmailField(max_length=100, null=True)
    latitude = models.CharField(max_length=10, null=True)
    longitude = models.CharField(max_length=11, null=True)


    def __unicode__(self):
        return unicode(self.company) + " - " + unicode(self.address) + " - " + unicode(self.contact_person) + " - " + unicode(self.email)


class campaign(models.Model):
    campaign_name = models.CharField(max_length=20)
    description = models.TextField(max_length=200)
    start_date = models.DateField(null=True)
    end_date = models.DateField(null=True)
    spent = models.DecimalField(decimal_places=2, max_digits=6)

    def __unicode__(self):
        return self.campaign_name


class contact_date(models.Model):
    CONTACT_CHOICES = (
                       ('email', 'email'),
                       ('person', 'person'),
                       ('twitter', 'twitter'),
                       ('facebook', 'facebook'),
                       ('Newsletter', 'Newsletter'),
                       )

    contacted = models.DateField()
    who = models.ForeignKey(User)
    how = models.CharField(max_length=15, choices=CONTACT_CHOICES)
    company = models.ForeignKey(company)
    campaign = models.ForeignKey(campaign)

    def __unicode__(self):
        return unicode(self.company) + " - " + unicode(self.contacted) + " - " + self.how  + " - " + unicode(self.campaign)


class questionaire_1(models.Model):
    SECTOR_CHOICES = (
                ('x', ''),
                ('0', 'Medical'),
                ('1', 'Vet'),
                ('2', 'Hair Dresser'),
                ('3', 'Beauty Salon'),
                ('4', 'Hospitality'),
                ('5', 'Retail'),
                ('6', 'Other')
                )
    IMPORTANCE_CHOICES = (
                    ('x', ''),
                    ('0', 'Very Important'),
                    ('1', 'Important'),
                    ('2', 'Moderately Important'),
                    ('3', 'Not That Important'),
                    ('4', 'Not at all important')
                    )
    ROYALTIES_CHOICES = (
                    ('x', ''),
                    ('0', 'no-I didnt know about them'),
                    ('1', 'no-but would like to'),
                    ('2', 'Yes'),
                    ('3', 'No, don\'t want to')
                    )
    SPEND_CHOICES = (
               ('x', ''),
               ('0', '$1000 or more'),
               ('1', '$500 or $1000'),
               ('2', '$200 to $500'),
               ('3', 'don\'t know'),
               ('4', 'Nothing')
               )
    INTERNET_CHOICES = (
               ('x', ''),
               ('0', 'Yes'),
               ('5', 'No')
               )
    INTERESTED_CHOICES = (
                    ('x', ''),
                    ('0', 'Yes'),
                    ('20', 'No')
                    )
    USEDNOW_CHOICES = (
                       ('x', ''),
                       ('Radio', 'Radio'),
                       ('Ipod', 'ipod'),
                       ('Streaming Radio', 'Streaming Radio'),
                       ('CDs', 'CDs')                       
                       )
    contact = models.ForeignKey(contact_date)
    sector = models.CharField(max_length=1, choices=SECTOR_CHOICES, null=True)
    importance = models.CharField(max_length=1, choices=IMPORTANCE_CHOICES, null=True)
    royalties = models.CharField(max_length=1, choices=ROYALTIES_CHOICES, null=True)
    spend = models.CharField(max_length=1, choices=SPEND_CHOICES, null=True)
    internet = models.CharField(max_length=1, choices=INTERNET_CHOICES, null=True)
    use_now = models.CharField(max_length=20, choices=USEDNOW_CHOICES, null=True)
    interested = models.CharField(max_length=2, choices=INTERESTED_CHOICES, null=True)
    score = models.IntegerField(null=True)
    comments = models.TextField(max_length=500, null=True)

    def calculate_score(self):
        if (self.sector == 'x') or (self.importance == 'x') or (self.royalties == 'x') or (self.spend == 'x') or (self.internet == 'x') or (self.interested == 'x'):
            self.sector = None
            self.importance = None
            self.royalties = None
            self.spend = None
            self.internet = None
            self.interested = None
            return None
        else:
            return int(self.sector) + int(self.importance) + int(self.royalties) + int(self.spend) + int(self.internet) + int(self.interested)

    def save(self, *args, **kwargs):
        self.score = self.calculate_score()
        super(questionaire_1, self).save(*args, **kwargs)

    def __unicode__(self):
        return unicode(self.contact)

class firstEmail(models.Model):
    contact = models.ForeignKey(contact_date)
    emailSent = models.BooleanField(default=False)
    whoTo = models.CharField(max_length = 50)
    MoreInformation = models.BooleanField(default=False)
    emailLink = models.CharField(max_length=75, null=True)
    comments = models.TextField(max_length=500, null=True)

    def constructEmailLink(self):
        return "infra.inthebackground.com" + reverse('inthebackgroundSite.marketing.views.confirm', args=[self.id])

    #watch out for potential DB hits on this one, as we are potentially saving twice.
    def save(self, *args, **kwargs):
        super(firstEmail, self).save(*args, **kwargs)
        self.emailLink = self.constructEmailLink()
        super(firstEmail, self).save(*args, **kwargs)

我的看法

    # Create your views here.


from django.shortcuts import render_to_response, get_list_or_404, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from inthebackgroundSite.marketing.models import campaign, company, contact_date, questionaire_1, firstEmail
from inthebackgroundSite.marketing.forms import AddNewEmailForm
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_protect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required





#######################################################
# view all details of contacts and their Questionaires
#
#######################################################

@    login_required
def viewAllDetails(request, contact_id):
    contactDetails = get_list_or_404(contact_date, id=contact_id)
    questionaireDetails = list(questionaire_1.objects.filter(contact=contact_id))
    firstEmailDetails = list(firstEmail.objects.filter(contact=contact_id))
    return render_to_response('marketing/viewAllDetails.html', 
                              {'contactDetails' : contactDetails, 'questionaireDetails' : questionaireDetails, 'firstEmailDetails' : firstEmailDetails})

#######################################################
# Takes a confirmation from the user that they are
# replying on behalf of a company. then submits a form
# that triggers emailMeAtLaunch()
#
#######################################################

@csrf_protect
d    ef confirm(request,firstEmail_id):
    firstEmailDetails = get_object_or_404(firstEmail, id=firstEmail_id)
    contactDetails = get_object_or_404(contact_date, id=firstEmailDetails.contact.id)
    companyDetails = get_object_or_404(company, id=contactDetails.company.id)
    campaignDetails = get_object_or_404(campaign, id=contactDetails.campaign.id)
    UserDetails = get_object_or_404(User, id=1)
    return render_to_response('marketing/confirm.html', {'firstEmailDetails': firstEmailDetails, 'companyDetails' : companyDetails}, context_instance=RequestContext(request))

########################################################
# This view updates the firstEmail table specified by the
# id passed in, setting MoreInformation to true.
#
########################################################

def emailMeAtLaunch(request,firstEmail_id):
    firstEmailDetails = get_object_or_404(firstEmail, id=firstEmail_id)
    contactDetails = get_object_or_404(contact_date, id=firstEmailDetails.contact.id)
    companyDetails = get_object_or_404(company, id=contactDetails.company.id)

    firstEmailDetails.MoreInformation = True
    firstEmailDetails.save()

    return render_to_response('marketing/thankyou.html', {'firstEmailDetails': firstEmailDetails, 'companyDetails' : companyDetails}, context_instance=RequestContext(request))

@csrf_protect
def addMeToMailingList(request):

    if request.method == 'POST':
        form = AddNewEmailForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('inthebackgroundSite.marketing.views.thankyou'))
    else:
        #print "not POST method"
        form = AddNewEmailForm()

    return render_to_response('marketing/addToMailingList.html', {'form': form }, context_instance=RequestContext(request))

def thankyou(request):
    return render_to_response('marketing/thankyou.html')

最后是我的表格(抱歉所有代码...)

import datetime

from django import forms
from inthebackgroundSite.marketing.models import campaign, company, contact_date, firstEmail
from django.db import transaction
from django.template import RequestContext
from django.shortcuts import render_to_response, get_list_or_404, get_object_or_404
from django.contrib.auth import authenticate
from django.contrib.auth.models import User

class AddNewEmailForm(forms.Form):
    ContactPerson = forms.CharField(max_length=200)
    email = forms.EmailField()

    #def __init__(self, *args, **kwargs):
    #    self.firstEmail_id = kwargs.pop('firstEmail_id', None)

    #@transaction.commit_on_success
    def save(self):
        now = datetime.date.today()

        UserDetails = get_object_or_404(User, id=1)
        campaignDetails = get_object_or_404(campaign, id=1)
        #orginalFirstEmail = get_object_or_404(firstEmail, id=self.firstEmail_id)
        #originalContact = get_object_or_404(contact_date, id=orginalFirstEmail.contact.id)
        #originalCompany = get_object_or_404(company, id=originalContact.company.id)
        newCompany = company.objects.create(company = "unknown",
                                            address = "unknown",
                                            street = "unknown",
                                            suburb = "unknown",
                                            phone_number = "unknown",
                                            contact_person = self.cleaned_data['ContactPerson'],
                                            email = self.cleaned_data['email'],
                                            latitude = None,
                                            longitude = None
                                            )
        print str(newCompany.id) + ": " + unicode(newCompany)
        newContact = contact_date.objects.create(contacted = now,
                                                 who = UserDetails,
                                                 how = 'email',
                                                 company = newCompany,
                                                 campaign = campaignDetails
                                                 )
        print str(newContact.id) + ": " + unicode(newContact)
        newFirstEmail = firstEmail.objects.create(contact = newContact,
                                                  emailSent = False,
                                                  whoTo = "unknown",
                                                  MoreInformation = True,
                                                  comments = "This is a new addition to the mailing list that came from an unknown company.\n The company that this email was sent to is in the WhoTo",
                                                  )
        print str(newFirstEmail.id) + ": " + unicode(newFirstEmail)

我遇到的问题是

重复键值违反唯一约束“marketing_firstemail_pkey”

如果我直接将数据加载到 postgres 并且没有更新 id 的序列,通常会出现这个问题。但是我在这个表中没有任何数据......没有!我仍然收到此错误。我不明白这是怎么发生的。

任何帮助都会很棒!

最佳答案

我觉得还是需要调用父对象(Form)的save方法。在覆盖方法的开头:

super(AddNewEmailForm, self).save()

关于django "duplicate key value violates unique constraint"主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4988094/

相关文章:

django - 使用内联表单集创建模型和相关模型

Django和crispy form,如何在crispy Layout中添加id和name

postgresql - 在 postgis/postgresql 中计算点距离

html - 如何在 50% 宽度和 50% 高度的容器中排列 div?

django - Django ORM 中的替代 nullif

python - Django 时间戳

postgresql - 如何配置 docker 和 postgres 以使用 pact broker

sql - 每天查询数周内有日期限制的计数

php - Symfony2 带有复选框表单的扩展表

Javascript 表单提交有时不起作用