0

I have a Django application with some fairly common models in it: UserProfile and Organization. A UserProfile or an Organization can both have 0 to n emails, so I have an Email model that has a GenericForeignKey. UserProfile and Organization Models both have a GenericRelation called emails that points back to the Email model (summary code provided below).

The question: what is the best way to provide an Organization form that allows a user to enter organization details including 0 to n email addresses?

My Organization create view is a Django class-based view. I'm leaning towards creating a dynamic form and an enabling it with Javascript to allow the user to add as many email addresses as necessary. I will render the form with django-crispy-forms and django-floppyforms for display on a site using Twitter Bootstrap.

I've thought about doing this with a BaseGenericInlineFormset embedded within the form, but this seems like overkill for email addresses. Embedding a formset in a form delivered by a class-based view is cumbersome too.

Note that the same issue occurs with the Organization fields phone_numbers and locations.

Code

emails.py:

from django.db import models
from parent_mixins import Parent_Mixin

class Email(Parent_Mixin,models.Model):
    email_type = models.CharField(blank=True,max_length=100,null=True,default=None,verbose_name='Email Type')
    email = models.EmailField()

    class Meta:
        app_label = 'core'

organizations.py:

from emails import Email
from locations import Location
from phone_numbers import Phone_Number
from django.contrib.contenttypes import generic
from django.db import models

class Organization(models.Model):
    active = models.BooleanField()
    duns_number = models.CharField(blank=True,default=None,null=True,max_length=9)  # need to validate this
    emails = generic.GenericRelation(Email,content_type_field='parent_type',object_id_field='parent_id')
    legal_name = models.CharField(blank=True,default=None,null=True,max_length=200)
    locations = generic.GenericRelation(Location,content_type_field='parent_type',object_id_field='parent_id')
    name = models.CharField(blank=True,default=None,null=True,max_length=200)
    organization_group = models.CharField(blank=True,default=None,null=True,max_length=200)
    organization_type = models.CharField(blank=True,default=None,null=True,max_length=200)
    phone_numbers = generic.GenericRelation(Phone_Number,content_type_field='parent_type',object_id_field='parent_id')
    taxpayer_id_number = models.CharField(blank=True,default=None,null=True,max_length=9)  # need to validate this

    class Meta:
        app_label = 'core'

parent_mixins.py

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.db import models

class Parent_Mixin(models.Model):
    parent_type = models.ForeignKey(ContentType,blank=True,null=True)
    parent_id = models.PositiveIntegerField(blank=True,null=True)
    parent = generic.GenericForeignKey('parent_type', 'parent_id')

    class Meta:
        abstract = True
        app_label = 'core'
Erik
  • 7,479
  • 8
  • 62
  • 99
  • I think the best way to go about this is - like you mentioned - to use a formset (even if it seems like overkill). – Timmy O'Mahony Oct 15 '12 at 09:02
  • I simplified this question a bit and found an answer: http://stackoverflow.com/questions/12890919/django-class-based-views-and-formsets/12905947#12905947. – Erik Oct 16 '12 at 00:37

1 Answers1

2

you can try using .split(), with this your form would look easier and users wont have to keep on adding text fields. What you can do is, make one textbox where user can add multiple emails and separate them by a coma. and then in your views you can do this

email = emails.split(',')
for i in emails:
    #assign email and save.

in case of having an email type

it might still be a good idea to build a system like that. what you can do is

abc@gmail.com-work,xyz@k.com-school

and then you can split them like this

email-type=email.split(',')
for i in email-type:
    email=i.split('-')[0]
    if i.split('-')[1]:
        type=i.split('-')[1]
    else:
        #give it a default type
Jonathan
  • 2,728
  • 10
  • 43
  • 73
  • That's a pretty good idea, but I also store the type of email (home, office, etc.) along with the email address itself. For the case of addresses it's even worse. Thanks for the idea though -- I'm still struggling with this one. – Erik Oct 15 '12 at 22:49