Django - 将我的模型链接到配置文件(UserProfile)模型

时间:2021-09-13 20:57:00

I'm trying to create a small app for users to have contacts. I'm using django-profiles as a base for my profiles. Now everything works well until I try to submit the edit contact form and I receive this error.

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

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

Being pretty new to Django, I'm not even sure if I'm taking the right approach here. My end goal is for the user to be able to add as many contacts as neccessary. Any advice is appreciated.

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

My UserProfile model which extends User looks like:

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

and my contact model looks like this:

我的联系模式如下:

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)

and my view:

和我的观点:

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 个解决方案

#1


9  

Basically django-profiles is for something else - it's just helping to create and manage user profiles across an application.

基本上django-profiles用于其他方面 - 它只是帮助在应用程序中创建和管理用户配置文件。

First of all - you should link Contact models directly to the django.contrib.auth.models.User via ForeignKey. This way you can access given User's contacts by a simple query ie. User.contact_set.all() - it will return to you a list of User's contacts. This will also get rid off your error.

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

Second - fileds like first_name, last_name are already definied in django.contrib.auth.models.User, so there is no need to define them again in UserProfile. Read the source of User model here: http://goo.gl/8oDv3

第二个 - 像first_name,last_name这样的文件已经在django.contrib.auth.models.User中定义,所以不需要在UserProfile中再次定义它们。在此处阅读用户模型的来源:http://goo.gl/8oDv3

Third - if your user can only have one Profile and you're not intend to use very old versions of django then you should be using OneToOneField instead of ForeignKey.

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

Fourth thing - you could probably omit usage of RequestContext() by using one of the generic views bundled with django - read about that here: http://goo.gl/U4DWs

第四件事 - 您可以通过使用与django捆绑在一起的通用视图来省略RequestContext()的使用 - 请在此处阅读:http://goo.gl/U4DWs

Last thing - remember that main model for handling the Users is the User model itself. Any custom Profile is just an extension, so link everything which is related to the User to the User model itself.

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

Happy coding!

快乐的编码!

#2


1  

To elaborate on bx2's answer, your Contact model should look more like this:

要详细说明bx2的答案,您的Contact模型看起来应该更像这样:

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)

Your view, frankly, does not make much sense. In general an inline formset is meant to represent records related to some parent record. In your case, it would be the user record, with the contacts being the "children" records. But having both a Contact form and an AddContactFormset doesn't make a lot of sense.

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

Also, I'd recommend against using variable names like f and fs in Django. Apart from variables like indexes, counters, etc. it doesn't serve any purpose to use short 1-2 character variable names. Go ahead and use longer variable names like form and formset, or even contact_form and contact_formset. It makes it much, much easier to debug the code in the future.

另外,我建议不要在Django中使用变量名,如f和fs。除了索引,计数器等变量之外,它不能用于使用短1-2字符变量名称。继续使用更长的变量名称,例如form和formset,甚至是contact_form和contact_formset。它使得将来调试代码变得更加容易。

#1


9  

Basically django-profiles is for something else - it's just helping to create and manage user profiles across an application.

基本上django-profiles用于其他方面 - 它只是帮助在应用程序中创建和管理用户配置文件。

First of all - you should link Contact models directly to the django.contrib.auth.models.User via ForeignKey. This way you can access given User's contacts by a simple query ie. User.contact_set.all() - it will return to you a list of User's contacts. This will also get rid off your error.

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

Second - fileds like first_name, last_name are already definied in django.contrib.auth.models.User, so there is no need to define them again in UserProfile. Read the source of User model here: http://goo.gl/8oDv3

第二个 - 像first_name,last_name这样的文件已经在django.contrib.auth.models.User中定义,所以不需要在UserProfile中再次定义它们。在此处阅读用户模型的来源:http://goo.gl/8oDv3

Third - if your user can only have one Profile and you're not intend to use very old versions of django then you should be using OneToOneField instead of ForeignKey.

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

Fourth thing - you could probably omit usage of RequestContext() by using one of the generic views bundled with django - read about that here: http://goo.gl/U4DWs

第四件事 - 您可以通过使用与django捆绑在一起的通用视图来省略RequestContext()的使用 - 请在此处阅读:http://goo.gl/U4DWs

Last thing - remember that main model for handling the Users is the User model itself. Any custom Profile is just an extension, so link everything which is related to the User to the User model itself.

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

Happy coding!

快乐的编码!

#2


1  

To elaborate on bx2's answer, your Contact model should look more like this:

要详细说明bx2的答案,您的Contact模型看起来应该更像这样:

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)

Your view, frankly, does not make much sense. In general an inline formset is meant to represent records related to some parent record. In your case, it would be the user record, with the contacts being the "children" records. But having both a Contact form and an AddContactFormset doesn't make a lot of sense.

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

Also, I'd recommend against using variable names like f and fs in Django. Apart from variables like indexes, counters, etc. it doesn't serve any purpose to use short 1-2 character variable names. Go ahead and use longer variable names like form and formset, or even contact_form and contact_formset. It makes it much, much easier to debug the code in the future.

另外,我建议不要在Django中使用变量名,如f和fs。除了索引,计数器等变量之外,它不能用于使用短1-2字符变量名称。继续使用更长的变量名称,例如form和formset,甚至是contact_form和contact_formset。它使得将来调试代码变得更加容易。