Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Linking my models to profiles (UserProfile) model

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.

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.

My UserProfile model which extends User looks like:

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))
like image 780
tkh44 Avatar asked Dec 13 '22 18:12

tkh44


1 Answers

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

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.

Second - fields 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

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.

Fourth thing - you could probably omit usage of RequestContext() by using one of the generic views bundled with django - read about that here

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!

like image 170
bx2 Avatar answered Feb 03 '23 15:02

bx2