Django - Связывание моих моделей с профилями (UserProfile) модели - PullRequest
3 голосов
/ 22 ноября 2010

Я пытаюсь создать небольшое приложение для пользователей, чтобы иметь контакты.Я использую django-профили в качестве основы для своих профилей.Теперь все работает хорошо, пока я не попытаюсь отправить контактную форму для редактирования и не получу эту ошибку.

Cannot assign "<Contact: Contact object>": "Contact.user" must be a "UserProfile" instance.

Будучи довольно новым для Django, я даже не уверен, что я выбрал правильный подход здесь.Моя конечная цель - чтобы пользователь мог добавить столько контактов, сколько нужно.Любой совет приветствуется.

Моя модель UserProfile, которая расширяет пользователя выглядит следующим образом:

class UserProfile(models.Model):
#User's Info
user = models.ForeignKey(User, unique=True)
first_name = models.CharField("first name", max_length=30)
last_name = models.CharField("last name", max_length=30)
home_address = models.CharField(max_length=50)
primary_phone = PhoneNumberField()
city = models.CharField(max_length=50)
state = USStateField()
zipcode = models.CharField(max_length=5)
birth_date = models.DateField()
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True)

и моя модель контакта выглядит следующим образом:

class Contact(models.Model):    
user = models.ForeignKey(UserProfile)

contact_description = models.CharField("Relation or Description of Contact", max_length=50, blank=True)
contact_first_name = models.CharField("contact first name", max_length=30)
contact_last_name = models.CharField("contact last name", max_length=30)
contact_primary_phone = PhoneNumberField("contact primary phone number")
contact_secondary_phone = PhoneNumberField("contact secondary phone number",blank=True)

и мой взгляд:

def editContact(request, username, object_id=False, template_name='contacts/edit.html'):

user = UserProfile.user

AddContactFormset = inlineformset_factory(UserProfile,Contact, extra=1)
if object_id:
    contact=Contact.objects.get(pk=object_id)
else:
    contact=Contact()
if request.method == 'POST':
    f= ContactForm(request.POST, request.FILES, instance=contact)
    fs = AddContactFormset(request.POST, instance=contact)
    if fs.is_valid() and f.is_valid():
        f.save()
        fs.save()
        return HttpResponse('success')
else:
    f = ContactForm(instance=contact)
    fs = AddContactFormset(instance=contact)

return render_to_response(template_name ,{'fs':fs,'f':f,'contact': contact}, context_instance=RequestContext(request))

Ответы [ 2 ]

9 голосов
/ 22 ноября 2010

В основном django-профили предназначены для чего-то другого - они просто помогают создавать и управлять профилями пользователей в приложении.

Прежде всего - вы должны связать Contact модели напрямую с django.contrib.auth.models.User через ForeignKey. Таким образом, вы можете получить доступ к контактам данного пользователя с помощью простого запроса, т.е. User.contact_set.all() - вернет вам список контактов пользователя. Это также избавит вас от вашей ошибки.

Второе - поля типа first_name, last_name уже определены в django.contrib.auth.models.User, поэтому нет необходимости определять их снова в UserProfile. Читайте источник модели пользователя здесь: http://goo.gl/8oDv3

Третье - если ваш пользователь может иметь только один профиль, и вы не собираетесь использовать очень старые версии django, тогда вам следует использовать OneToOneField вместо ForeignKey.

В-четвертых, вы, вероятно, можете опустить использование RequestContext(), используя одно из общих представлений, связанных с django - читайте об этом здесь: http://goo.gl/U4DWs

И последнее - помните, что основной моделью для работы с пользователями является сама модель User. Любой пользовательский профиль - это просто расширение, поэтому свяжите все, что связано с пользователем, с самой моделью пользователя.

Удачного кодирования!

1 голос
/ 23 ноября 2010

Для уточнения ответа bx2 ваша модель контакта должна выглядеть примерно так:

class Contact(models.Model):    
    user = models.ForeignKey(User, related_name='contacts')
    contact_description = models.CharField("Relation or Description of Contact", max_length=50, blank=True)
    contact_first_name = models.CharField("contact first name", max_length=30)
    contact_last_name = models.CharField("contact last name", max_length=30)
    contact_primary_phone = PhoneNumberField("contact primary phone number")
    contact_secondary_phone = PhoneNumberField("contact secondary phone number",blank=True)

Ваш взгляд, честно говоря, не имеет особого смысла.В целом, встроенный набор форм предназначен для представления записей, относящихся к некоторой родительской записи.В вашем случае это будет запись пользователя, а контакты будут «дочерними» записями.Но наличие формы Contact и AddContactFormset не имеет большого смысла.

Кроме того, я бы рекомендовал не использовать имена переменных, такие как f и fs в Django.Помимо переменных, таких как индексы, счетчики и т. Д., Не имеет смысла использовать короткие 1-2-символьные имена переменных.Продолжайте и используйте более длинные имена переменных, такие как form и formset или даже contact_form и contact_formset.Это значительно упрощает отладку кода в будущем.

...