2011-02-16 286 views
0

我試圖修復我的網站上的rsvp系統。我有與用戶模型鏈接的聯繫人模型。訪客模型與聯繫人和事件模型相關聯。Django模型繼承

class Contact(models.Model): 
first_name = models.CharField(_("First name"), max_length=30,) 
last_name = models.CharField(_("Last name"), max_length=30,) 
user = models.ForeignKey(User, unique=True) 
dob = models.DateField(_("Date of birth"), blank=True, null=True) 
email = models.EmailField(_("Email"), blank=True, max_length=75) 
notes = models.TextField(_("Notes"), max_length=500, blank=True) 
create_date = models.DateField(_("Creation date")) 

class Guest(models.Model): 
event = models.ForeignKey(Event, related_name='guests') 
contact = models.ForeignKey(Contact, related_name='guests') 
attending_status = models.CharField(max_length=32, choices=ATTENDING_CHOICES, default='no_rsvp') 
number_of_guests = models.SmallIntegerField(default=0) 
comment = models.CharField(max_length=255, blank=True, default='') 
updated = models.DateTimeField(blank=True, null=True) 

def _get_email(self): 
    return u'%s' % (self.contact.email) 
email = property(_get_email) 

.... 

我嘗試修復旅客模型的基礎上RSVP形式:

class RSVPForm(forms.Form): 
email = forms.EmailField() 
name = forms.CharField(max_length=128) 
attending = forms.ChoiceField(choices=VISIBLE_ATTENDING_CHOICES, initial='yes', widget=forms.RadioSelect) 
number_of_guests = forms.IntegerField(initial=0) 
comment = forms.CharField(max_length=255, required=False, widget=forms.Textarea) 

def __init__(self, *args, **kwargs): 
    if 'guest_class' in kwargs: 
     self.guest_class = kwargs['guest_class'] 
     del(kwargs['guest_class']) 
    else: 
     self.guest_class = Guest 
    super(RSVPForm, self).__init__(*args, **kwargs) 

def clean_email(self): 
    try: 
     guest = self.guest_class.objects.get(email=self.cleaned_data['email']) 
    except ObjectDoesNotExist: 
     raise forms.ValidationError, 'That e-mail is not on the guest list.' 

    if hasattr(guest, 'attending_status') and guest.attending_status != 'no_rsvp': 
     raise forms.ValidationError, 'You have already provided RSVP information.' 

    return self.cleaned_data['email'] 

def clean_number_of_guests(self): 
    if self.cleaned_data['number_of_guests'] < 0: 
     raise forms.ValidationError, "The number of guests you're bringing can not be negative." 
    return self.cleaned_data['number_of_guests'] 

def save(self): 
    guest = self.guest_class.objects.get(email=self.cleaned_data['email']) 

    if self.cleaned_data['name']: 
     guest.name = self.cleaned_data['name'] 

    guest.attending_status = self.cleaned_data['attending'] 
    guest.number_of_guests = self.cleaned_data['number_of_guests'] 
    guest.comment = self.cleaned_data['comment'] 
    guest.save() 
    return guest 

這種形式由下面的視圖處理:

@login_required 
def event_view(request, slug, model_class=Event, form_class=RSVPForm, template_name='rsvp/event_view.html'): 
event = get_object_or_404(model_class, slug=slug) 

if request.POST: 
    form = form_class(request.POST) 

    if form.is_valid(): 
     guest = form.save() 
     return HttpResponseRedirect(reverse('rsvp_event_thanks', kwargs={'slug': slug, 'guest_id': guest.id})) 
else: 
    form = form_class() 

return render_to_response(template_name, { 
     'event': event, 
     'form': form, 
     }, context_instance=RequestContext(request)) 

提交表單後,我出現以下錯誤:

「無法將關鍵字'電子郵件'解析爲字段。可以選擇:attending_status,評論,聯繫,事件,身份證,number_of_guests,更新「

經過幾個小時的搜索網絡,我仍然無法弄清楚爲什麼我在選擇列表中只是」聯繫「,而我正在使用Guest.email從Contact.email呈現其值。

回答

1

您的模型中的來賓沒有字段電子郵件。它在您的聯繫人模型上。

你沒有提到這行觸發你的錯誤,但我猜這將是其中之一:

guest = self.guest_class.objects.get(email=self.cleaned_data['email']) 

如果您正在搜索鏈接到的聯繫人與給定客人電子郵件,你會想改變它使用contact__email所以它會做的加入爲你:

guest = self.guest_class.objects.get(contact__email=self.cleaned_data['email']) 

你的問題的根源也許是認爲你有你的模型之間的繼承關係,我沒有看到一個。你有一個簡單的ForeignKey關係,它應該適用於你,只是不要將它與繼承混淆起來,在這裏你將建立一個Guest來通過子類繼承Contact的屬性。

+0

Kekoa,你是對的。那正是問題所在。下次我會放回一個回溯。你剛剛學到了很好的一課。謝謝! – Yulia 2011-02-16 17:33:50

0

因爲django的ORM在SQL級別上工作。在你的表/模型中沒有'email'列(或定義的字段),只有一個python屬性。 Django不知道它需要加入到其他表中。

所以,應該使用Django的__ JOIN /場查找語法:

guest = self.guest_class.objects.get(contact__email=self.cleaned_data['email']) 

http://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships

+0

Yuji,作爲一件輕而易舉的工作!謝謝! – Yulia 2011-02-16 17:31:17