| 1 | from django.db import models
|
|---|
| 2 | from django.forms import ModelForm
|
|---|
| 3 | from django import forms
|
|---|
| 4 | from django.contrib.auth.models import User
|
|---|
| 5 | import datetime, string
|
|---|
| 6 |
|
|---|
| 7 | from django.contrib.localflavor.ca.forms import *
|
|---|
| 8 |
|
|---|
| 9 | import logging
|
|---|
| 10 |
|
|---|
| 11 | # for geocode/google maps
|
|---|
| 12 | import urllib
|
|---|
| 13 | developerKey = 'ABQIAAAAaZ9ti9DYuSfLcXWDENEwhRT2yXp_ZAY8_ufC3CFXhHIE1NvwkxT-5QCs51uXc6BPYK9UW8NiAo8qEg'
|
|---|
| 14 |
|
|---|
| 15 | ENTITY_ROLE_CHOICES = (
|
|---|
| 16 | ('ART', 'Artist'),
|
|---|
| 17 | ('BEN', 'Beneficiary'),
|
|---|
| 18 | ('MEM', 'EAC Member'),
|
|---|
| 19 | ('JUR', 'Juror'),
|
|---|
| 20 | ('NPO', 'Non-Profit Organization'),
|
|---|
| 21 | ('PAT', 'Patron'),
|
|---|
| 22 | ('PRO', 'Promoter'),
|
|---|
| 23 | ('VEN', 'Venue'),
|
|---|
| 24 | )
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 | class Entity(models.Model):
|
|---|
| 28 | role = models.CharField(max_length=3, blank=False, choices=ENTITY_ROLE_CHOICES)
|
|---|
| 29 | organization = models.ForeignKey('Organization', blank=True, null=True)
|
|---|
| 30 | person = models.ForeignKey('Person', null=True)
|
|---|
| 31 |
|
|---|
| 32 | def get_absolute_url(self):
|
|---|
| 33 | return "/entity/detail/%i/" % self.id
|
|---|
| 34 | def __unicode__(self):
|
|---|
| 35 | if self.organization.name:
|
|---|
| 36 | return "%s: %s" % (self.role, self.organization.name)
|
|---|
| 37 | else:
|
|---|
| 38 | return "%s: %s, %s" % (self.role, self.person.last_name, self.person.first_name)
|
|---|
| 39 |
|
|---|
| 40 | def name(self):
|
|---|
| 41 | if self.organization is None:
|
|---|
| 42 | return self.person.name()
|
|---|
| 43 | else:
|
|---|
| 44 | return self.organization.name
|
|---|
| 45 | class Meta:
|
|---|
| 46 | # ordering = [self.name]
|
|---|
| 47 | verbose_name_plural = "entities"
|
|---|
| 48 |
|
|---|
| 49 | class Organization(models.Model):
|
|---|
| 50 | name = models.CharField(max_length=500)
|
|---|
| 51 | check_pay_to = models.CharField(max_length=500, blank=True)
|
|---|
| 52 | address = models.ManyToManyField('Address', null=True)
|
|---|
| 53 | telephone = models.ManyToManyField('Telephone',null=True)
|
|---|
| 54 | email_address = models.EmailField(max_length=75, blank=True)
|
|---|
| 55 | email_accepted = models.BooleanField()
|
|---|
| 56 | website_url = models.URLField(verify_exists=False, max_length=200, blank=True)
|
|---|
| 57 | updated = models.DateTimeField(auto_now=True)
|
|---|
| 58 |
|
|---|
| 59 | def get_absolute_url(self):
|
|---|
| 60 | return "/entity/organization/detail/%i/" % self.id
|
|---|
| 61 | def __unicode__(self):
|
|---|
| 62 | return self.name
|
|---|
| 63 |
|
|---|
| 64 | NAME_PREFIX_CHOICES = (
|
|---|
| 65 | ('MS', 'Ms.'),
|
|---|
| 66 | ('MI', 'Miss'),
|
|---|
| 67 | ('MM', 'Mrs.'),
|
|---|
| 68 | ('MR', 'Mr.'),
|
|---|
| 69 | ('DR', 'Dr.'),
|
|---|
| 70 | ('HO', 'Hon.'),
|
|---|
| 71 | )
|
|---|
| 72 |
|
|---|
| 73 | class Person(models.Model):
|
|---|
| 74 | # Django_user_id =
|
|---|
| 75 | name_prefix = models.CharField(max_length=2, blank=True, choices=NAME_PREFIX_CHOICES )
|
|---|
| 76 | first_name = models.CharField(max_length=50, blank=False)
|
|---|
| 77 | middle_name = models.CharField(max_length=50, blank=True )
|
|---|
| 78 | last_name = models.CharField(max_length=50, blank=False)
|
|---|
| 79 | name_suffix = models.CharField(max_length=10, blank=True)
|
|---|
| 80 | address = models.ManyToManyField('Address')
|
|---|
| 81 | telephone = models.ManyToManyField('Telephone')
|
|---|
| 82 | email_address = models.EmailField(max_length=75, blank=True)
|
|---|
| 83 | email_accepted = models.BooleanField()
|
|---|
| 84 | website_url = models.URLField(verify_exists=False, max_length=200, blank=True)
|
|---|
| 85 | updated = models.DateTimeField(auto_now=True)
|
|---|
| 86 |
|
|---|
| 87 | def get_absolute_url(self):
|
|---|
| 88 | return "/entity/person/detail/%i/" % self.id
|
|---|
| 89 | def __unicode__(self):
|
|---|
| 90 | return "%s, %s %s" % (self.last_name, self.first_name, self.middle_name)
|
|---|
| 91 |
|
|---|
| 92 | def name(self):
|
|---|
| 93 | name_array = []
|
|---|
| 94 | if len(self.name_prefix) > 0:
|
|---|
| 95 | name_array.append(self.get_name_prefix_display())
|
|---|
| 96 | name_array.append( self.first_name )
|
|---|
| 97 | if len(self.niddle_name) > 0:
|
|---|
| 98 | name_array.append( self.middle_name )
|
|---|
| 99 | name_array.append( self.last_name )
|
|---|
| 100 | if len(self.name_suffix) > 0:
|
|---|
| 101 | name_array.append( self.name_suffix )
|
|---|
| 102 | return string.join( name_array )
|
|---|
| 103 |
|
|---|
| 104 | class PersonForm(ModelForm):
|
|---|
| 105 | class Meta:
|
|---|
| 106 | model = Person
|
|---|
| 107 | exclude = ['address', 'telephone', 'email_accepted', 'updated']
|
|---|
| 108 |
|
|---|
| 109 | class PersonNoURLForm(ModelForm):
|
|---|
| 110 | class Meta:
|
|---|
| 111 | model = Person
|
|---|
| 112 | exclude = ['address', 'telephone', 'email_accepted', 'updated', 'website_url']
|
|---|
| 113 |
|
|---|
| 114 |
|
|---|
| 115 | ADDRESS_TYPE_CHOICES = (
|
|---|
| 116 | ('P', 'Physical'),
|
|---|
| 117 | ('M', 'Mailing'),
|
|---|
| 118 | ('S', 'Shipping'),
|
|---|
| 119 | ('B', 'Billing'),
|
|---|
| 120 | )
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 | class Address(models.Model):
|
|---|
| 124 | address_type = models.CharField(max_length=1, choices=ADDRESS_TYPE_CHOICES, help_text='(required)')
|
|---|
| 125 | address_line_1 = models.CharField(max_length=100, help_text='')
|
|---|
| 126 | address_line_2 = models.CharField(max_length=100, null=True, blank=True)
|
|---|
| 127 | address_line_3 = models.CharField(max_length=100, null=True, blank=True)
|
|---|
| 128 | city = models.CharField(max_length=100, help_text='(required)')
|
|---|
| 129 | province = models.CharField(max_length=5, blank=False)
|
|---|
| 130 | country = models.CharField(max_length=22, blank=False)
|
|---|
| 131 | postal_code = models.CharField(max_length=8, null=True, blank=False, help_text='in A#A #A# format with no dash')
|
|---|
| 132 | latitude = models.FloatField(blank=True, null=True)
|
|---|
| 133 | longitude = models.FloatField(blank=True, null=True)
|
|---|
| 134 | updated = models.DateTimeField(auto_now=True)
|
|---|
| 135 | class Meta:
|
|---|
| 136 | # ordering = []
|
|---|
| 137 | verbose_name_plural = "addresses"
|
|---|
| 138 | def get_absolute_url(self):
|
|---|
| 139 | return "/entity/address/detail/%i/" % self.id
|
|---|
| 140 | def __unicode__(self):
|
|---|
| 141 | return "%s, %s" % (self.address_line_1, self.city)
|
|---|
| 142 |
|
|---|
| 143 | def address(self, name=None, sep="\n"):
|
|---|
| 144 | address_array = []
|
|---|
| 145 | if name != None:
|
|---|
| 146 | address_array.append( name )
|
|---|
| 147 | address_array.append( self.address_line_1)
|
|---|
| 148 | if self.address_line_2 is not None and len(self.address_line_2) > 0:
|
|---|
| 149 | address_array.append( self.address_line_1)
|
|---|
| 150 | address_array.append( self.city + ", " + self.province )
|
|---|
| 151 | address_array.append( self.country + " " + self.postal_code )
|
|---|
| 152 | return string.join(address_array, sep)
|
|---|
| 153 |
|
|---|
| 154 | def geocode(self):
|
|---|
| 155 |
|
|---|
| 156 | # Query Google Maps API with string containing address.
|
|---|
| 157 | # Returns string containing the latitude and longtitude of the address.
|
|---|
| 158 | # geocode('11044 82 Avenue NW, Edmonton, ab, canada') returns "53.5181678,-113.5162814"
|
|---|
| 159 | # Peter Matschek prescient1000@gmail.com
|
|---|
| 160 | # be sure to get a developer key for the site's domain as this is using my developer key and will work only for l
|
|---|
| 161 |
|
|---|
| 162 | gMapsURL = 'http://maps.google.com/maps/geo?q='
|
|---|
| 163 |
|
|---|
| 164 | if self.postal_code == 'A0A 0A0':
|
|---|
| 165 | postal_code = ''
|
|---|
| 166 | else:
|
|---|
| 167 | postal_code = self.postal_code
|
|---|
| 168 | address = "%s %s, %s, %s, %s, %s" % (self.address_line_1, self.address_line_2, self.city, self.province, self.country, postal_code)
|
|---|
| 169 | url = gMapsURL+urllib.quote(address)+'&output=csv&key='+developerKey
|
|---|
| 170 |
|
|---|
| 171 | coord = urllib.urlopen(url).read().split(',')
|
|---|
| 172 |
|
|---|
| 173 | self.latitude = coord[2]
|
|---|
| 174 | self.longitude = coord[3]
|
|---|
| 175 | # note: does not save change to DB
|
|---|
| 176 |
|
|---|
| 177 | def set_type(self, type):
|
|---|
| 178 | logging.debug('in set_type')
|
|---|
| 179 | self.address_type = type
|
|---|
| 180 |
|
|---|
| 181 | def get_type(self):
|
|---|
| 182 | return self.address_type
|
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 | if __name__ == '__main__':
|
|---|
| 186 | latlongString = geocode('11044 82 Avenue NW, Edmonton, ab, canada')
|
|---|
| 187 | print latlongString
|
|---|
| 188 |
|
|---|
| 189 |
|
|---|
| 190 | TELEPHONE_TYPE_CHOICES = (
|
|---|
| 191 | ('H', 'Home'),
|
|---|
| 192 | ('M', 'Mobile'),
|
|---|
| 193 | ('W', 'Business'),
|
|---|
| 194 | ('F', 'Fax'),
|
|---|
| 195 | )
|
|---|
| 196 |
|
|---|
| 197 | class Telephone(models.Model):
|
|---|
| 198 | telephone_number = models.CharField(max_length=15, help_text='(required)') # see http://en.wikipedia.org/wiki/E.164
|
|---|
| 199 | telephone_extension = models.CharField(max_length=10, blank=True, null=True, help_text='type extension number only - no letters')
|
|---|
| 200 | telephone_type = models.CharField(max_length=1, blank=False, choices=TELEPHONE_TYPE_CHOICES)
|
|---|
| 201 | updated = models.DateTimeField(auto_now=True)
|
|---|
| 202 |
|
|---|
| 203 | def get_absolute_url(self):
|
|---|
| 204 | return "/entity/telephone/detail/%i/" % self.id
|
|---|
| 205 | def __unicode__(self):
|
|---|
| 206 | if len(self.telephone_extension) > 0:
|
|---|
| 207 | return self.telephone_type + ': ' + self.telephone_number + " x" + self.telephone_extension
|
|---|
| 208 | else:
|
|---|
| 209 | return self.telephone_type + ': ' + self.telephone_number
|
|---|
| 210 |
|
|---|
| 211 | def telephone(self):
|
|---|
| 212 | if len(self.telephone_extension) > 0:
|
|---|
| 213 | return self.telephone_type + ': ' + self.telephone_number + " x" + self.telephone_extension
|
|---|
| 214 | else:
|
|---|
| 215 | return self.telephone_type + ': ' + self.telephone_number
|
|---|
| 216 |
|
|---|
| 217 | def set_type(self, type):
|
|---|
| 218 | self.telephone_type = type
|
|---|
| 219 |
|
|---|
| 220 | def get_type(self):
|
|---|
| 221 | return self.telephone_type
|
|---|
| 222 |
|
|---|
| 223 | class TelephoneForm(ModelForm):
|
|---|
| 224 | telephone_number = CAPhoneNumberField()
|
|---|
| 225 | class Meta:
|
|---|
| 226 | model = Telephone
|
|---|
| 227 | exclude = ['updated']
|
|---|
| 228 |
|
|---|
| 229 |
|
|---|
| 230 | class TelephoneFormNoType(ModelForm): # in some situations type should preassigned
|
|---|
| 231 | telephone_number = CAPhoneNumberField()
|
|---|
| 232 | class Meta:
|
|---|
| 233 | model = Telephone
|
|---|
| 234 | fields = ['telephone_number','telephone_extension']
|
|---|
| 235 |
|
|---|
| 236 | """
|
|---|
| 237 | #The following works, and is preferable since it sets the class of the input field for skinning,
|
|---|
| 238 | #but doesn't work if TelephoneFormNoType is subclassed with other ModelForms
|
|---|
| 239 | class TelephoneFormNoType(forms.Form):
|
|---|
| 240 | telephone_number = CAPhoneNumberField(
|
|---|
| 241 | widget=forms.TextInput(attrs={
|
|---|
| 242 | 'class':'phone',
|
|---|
| 243 | }
|
|---|
| 244 | )
|
|---|
| 245 | )
|
|---|
| 246 | telephone_extension = forms.CharField(
|
|---|
| 247 | widget=forms.TextInput(attrs={
|
|---|
| 248 | 'class':'phone-ext',
|
|---|
| 249 | }
|
|---|
| 250 | )
|
|---|
| 251 | )
|
|---|
| 252 | class Meta:
|
|---|
| 253 | model = Telephone
|
|---|
| 254 | """
|
|---|
| 255 |
|
|---|
| 256 | class AddressForm(ModelForm):
|
|---|
| 257 | postal_code = CAPostalCodeField()
|
|---|
| 258 | province = CAProvinceField()
|
|---|
| 259 | class Meta:
|
|---|
| 260 | model = Address
|
|---|
| 261 | exclude = ['latitude', 'longitude', 'updated']
|
|---|
| 262 |
|
|---|
| 263 | class AddressFormNoType(ModelForm):
|
|---|
| 264 | postal_code = CAPostalCodeField()
|
|---|
| 265 | province = CAProvinceField()
|
|---|
| 266 | class Meta:
|
|---|
| 267 | model = Address
|
|---|
| 268 | exclude = ['address_type', 'latitude', 'longitude', 'updated']
|
|---|
| 269 |
|
|---|
| 270 |
|
|---|