【问题标题】:Django - Linking my models to profiles (UserProfile) modelDjango - 将我的模型链接到配置文件(UserProfile)模型
【发布时间】:2011-05-14 01:47:59
【问题描述】:

我正在尝试为用户创建一个小应用程序以建立联系人。我使用 django-profiles 作为我的个人资料的基础。现在一切正常,直到我尝试提交编辑联系表单并收到此错误。

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

作为 Django 的新手,我什至不确定我是否在这里采用了正确的方法。我的最终目标是让用户能够根据需要添加尽可能多的联系人。 任何建议表示赞赏。

我的扩展 User 的 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))

【问题讨论】:

  • 为什么你对个人资料有一个 FK 而不是对用户本身?

标签: django django-models django-views


【解决方案1】:

基本上,django-profiles 用于其他用途 - 它只是帮助创建和管理跨应用程序的用户配置文件。

首先 - 您应该通过 ForeignKey 将 Contact 模型直接链接到 django.contrib.auth.models.User。这样,您可以通过简单的查询访问给定用户的联系人,即。 User.contact_set.all() - 它将返回给您用户的联系人列表。这也将消除您的错误。

第二个 - first_namelast_name 等字段已经在 django.contrib.auth.models.User 中定义,因此无需在 UserProfile 中再次定义它们。阅读User模型here的源码

第三 - 如果您的用户只能拥有一个配置文件并且您不打算使用非常旧版本的 django,那么您应该使用 OneToOneField 而不是 ForeignKey

第四件事 - 您可能会通过使用与 django 捆绑在一起的通用视图之一来省略 RequestContext() 的使用 - 请阅读 here

最后一件事 - 请记住,处理用户的主要模型是 User 模型本身。任何自定义配置文件都只是一个扩展,因此将与用户相关的所有内容链接到用户模型本身。

编码愉快!

【讨论】:

【解决方案2】:

详细说明bx2's answer,您的联系人模型应该更像这样:

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)

坦率地说,你的观点没有多大意义。通常,内联表单集旨在表示与某些父记录相关的记录。在您的情况下,它将是用户记录,联系人是“儿童”记录。但是同时拥有一个联系表单和一个 AddContactFormset 并没有多大意义。

另外,我建议不要在 Django 中使用像 ffs 这样的变量名。除了索引、计数器等变量外,使用 1-2 个字符的短变量名没有任何用途。继续使用更长的变量名,如formformset,甚至contact_formcontact_formset。它使将来调试代码变得更加容易。

【讨论】:

    猜你喜欢
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多