我从我写的一个表单中得到了一些非常奇怪的错误。
使用: postgres 8.4 ubuntu 10.04 oython 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的序列,那么通常会出现这个问题。但我这张表中没有任何数据......没有!我仍然得到这个错误..我不明白这是怎么发生的。
任何帮助都会很棒!
答案 0 :(得分:2)
我认为你仍然需要调用父对象(Form)的save方法。在覆盖方法的开头:
super(AddNewEmailForm, self).save()
答案 1 :(得分:2)
所以我弄清楚它是什么。
这是因为我在模型save()方法中做了一次黑客攻击。我没有使用属性来计算emailLink的值,而是将模型保存两次。当发生这种情况时,我认为Django会缓存模型然后再次尝试保存它。删除自定义保存表单并用此
替换电子邮件链接 def constructEmailLink(self):
return "http://www.domain.com" + reverse('inthebackgroundSite.marketing.views.confirm', args=[self.id])
emailLink = property(constructEmailLink)
做了这个伎俩。谢谢你的帮助!