Джанго модель наследования - PullRequest
0 голосов
/ 16 февраля 2011

Я пытаюсь исправить систему rsvp на моем сайте. У меня есть модель контакта, которая связана с моделью пользователя. Гостевая модель связана с моделями контактов и событий.

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 на основе модели Guest:

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

После отправки формы я получаю следующую ошибку:

«Невозможно разрешить ключевое слово« электронная почта »в поле. Возможные варианты: присутствующий_статус, комментарий, контакт, событие, идентификатор, номер_фона_гестей, обновлено"

После нескольких часов поиска в Интернете я все еще не могу понять, почему у меня есть просто "контакт" в списке выбора, когда я работаю с Guest.email, который отображает его значение из Contact.email ..

Ответы [ 2 ]

1 голос
/ 16 февраля 2011

Гость в ваших моделях не имеет поля email.Это в вашей модели контактов.

Вы не упомянули, какая строка вызвала вашу ошибку, но я предполагаю, что это будет одна из следующих причин:

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, которые должны работать для вас, только не путайте их с наследованием, где вы бы настроили гостя для наследования свойств Contact через подклассы.

0 голосов
/ 16 февраля 2011

Потому что ORM в django работает на уровне SQL. В ваших таблицах / модели нет столбца '' email '' (или определенного поля), есть только свойство python. Джанго не знает, что ему нужно присоединиться к другому столу.

Вместо этого просто используйте 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...