Re: Zip code lookup field

2007-06-27 Thread leif strickland

I figured it out!

The problem was that my custom zip code field's clean() function was
returning the profile object's *id*, not the actual zip code
instance.

>  zip_code_id = Postal_Code.objects.get(postal_code=value).id
>  return int(zip_code_id)

As it turns out, the function should have returned the actual object.
All I had to do to make this code work, therefore, was remove the
".id" from the end of the first line above. Voila!

Lesson learned: Custom fields for foreign keys must return an
instance, not the key.

Thanks again for the help. Hope this thread helps someone else in the
future.

Cheers,
LS



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

Here's a bit of the testing I have run in the shell...
>>> from mysite2.profile.models import Profile
>>> from django import newforms
>>> from mysite2.admin import ProfileOptions
>>> # instantiate a Profile object
>>> test_profile = Profile.objects.get(id=1)

>>> # instantiate the adminoptions class
>>> # used by the admin site
>>> options = ProfileOptions(Profile)

>>> # create a form class for the profile instance
>>> form = newforms.form_for_instance(test_profile,formfield_callback = 
>>> options.formfield_for_dbfield)
>>> form



>>> # check that the zip_code field is of type ZipCodeField
>>> form.base_fields['zip_code']



>>> # in my database, i currently have only one zip code
>>> # 90069, with a key of 1.

>>> form.base_fields['zip_code'].initial
1

>>> form.base_fields['zip_code'].clean(value='90069')
1

>>> form.base_fields['zip_code'].clean(value='111')


Traceback (most recent call last):
  File "", line 1, in ?
  File "Sites/Django/mysite2/../mysite2/admin.py", line 40, in clean
raise ValidationError, "Please enter a valid zip code."
ValidationError: [u'Please enter a valid zip code.']
>>> form.base_fields['zip_code'].clean(value='')


Traceback (most recent call last):
  File "", line 1, in ?
  File "/Users/leifstrickland/Sites/DjangoProject/mysite2/../mysite2/
admin.py", line 40, in clean
raise ValidationError, "Please enter a valid zip code."
ValidationError: [u'Please enter a valid zip code.']
>>> zip_code_field = form.base_fields['zip_code']
>>> zip_code_field.widget.render(name='zip_code',value=1)


u''
>>> zip_code_field.widget.render(name='zip_code',value='')


u''
As you can see, everything seems to be working. I'm so puzzled...



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

Here's a bit of the testing I have run in the shell...


>>> from mysite2.profile.models import Profile
>>> from django import newformms
>>> from mysite2.admin import ProfileOptions
>>>
>>> # instantiate a Profile object
>>> test_profile = Profile.objects.get(id=1)
>>>
>>> # instantiate the adminoptions class
>>> # used by the admin site
>>> options = ProfileOptions(Profile)
>>>
>>> # create a form class for the profile instance
>>> form = newforms.form_for_instance(test_profile,formfield_callback = 
>>> options.formfield_for_dbfield)
>>> form

>>>
>>> # check that the zip_code field is of type ZipCodeField
>>> form.base_fields['zip_code']

>>>
>>> # in my database, i currently have only one zip code
>>> # 90069, with a key of 1.
>>>
>>> form.base_fields['zip_code'].initial
1
>>>
>>> form.base_fields['zip_code'].clean(value='90069')
1
>>>
>>> form.base_fields['zip_code'].clean(value='111')
Traceback (most recent call last):
  File "", line 1, in ?
  File "Sites/Django/mysite2/../mysite2/admin.py", line 40, in clean
raise ValidationError, "Please enter a valid zip code."
ValidationError: [u'Please enter a valid zip code.']
>>>
>>> form.base_fields['zip_code'].clean(value='')
Traceback (most recent call last):
  File "", line 1, in ?
  File "/Users/leifstrickland/Sites/DjangoProject/mysite2/../mysite2/
admin.py", line 40, in clean
raise ValidationError, "Please enter a valid zip code."
ValidationError: [u'Please enter a valid zip code.']
>>>
>>> zip_code_field = form.base_fields['zip_code']
>>> zip_code_field.widget.render(name='zip_code',value=1)
u''
>>>
>>> zip_code_field.widget.render(name='zip_code',value='')
u''

As you can see, everything seems to be working. I'm so puzzled...




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

Yes, the ModelAdmin is registered with django.contrib.admin.site. And
the change and add pages for the model are displaying correctly. It
even provides the expected error message if I enter an invalid Zip
code.
But when I enter a correct Zip code and Save, it gives me an
Integrity
Error:

---

IntegrityError at /admin/profile/profile/2/
null value in column "zip_code_id" violates not-null constraint

TRACEBACK

/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args,
**callback_kwargs) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/sites.py in root
return self.model_page(request, *url.split('/', 2)) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/sites.py in model_page
return admin_obj(request, rest_of_url) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in __call__
return self.change_view(request, unquote(url)) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in change_view
return self.save_change(request, model, form,
inline_formsets) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in save_change
new_object = form.save(commit=True) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/newforms/models.py in save
return save_instance(self, instance, fields, fail_message,
commit) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/newforms/models.py in save_instance
instance.save() ...
/Sites/Django/mysite2/../mysite2/profile/models.py in save
super(Profile, self).save()  ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/db/models/base.py in save
db_values + [pk_val]) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/db/backends/util.py in execute
return self.cursor.execute(sql, params) ...

---

In the last step, the local db_values var is a tuple of values to be
used in the DB query. All values are correct except for the
zip_code_id, which is None. That shouldn't be the case, because the
zip code field's clean() function has worked properly (i.e., returned
the corresponding zip_code_id) in shell and admin testing. So somehow
the value returned by the clean() function is being overwritten or
ignored later in the script. I just can't figure it out.

Thanks again for all the help.



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

Yes, the ModelAdmin is registered with django.contrib.admin.site. And
the change and add pages for the model are displaying correctly. It
even provides the expected error message if I enter an invalid Zip
code.

But when I enter a correct Zip code and Save, it gives me an Integrity
Error:

---

IntegrityError at /admin/profile/profile/2/
null value in column "zip_code_id" violates not-null constraint

TRACEBACK

/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args,
**callback_kwargs) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/sites.py in root
return self.model_page(request, *url.split('/', 2)) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/sites.py in model_page
return admin_obj(request, rest_of_url) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in __call__
return self.change_view(request, unquote(url)) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in change_view
return self.save_change(request, model, form,
inline_formsets) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/contrib/admin/options.py in save_change
new_object = form.save(commit=True) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/newforms/models.py in save
return save_instance(self, instance, fields, fail_message,
commit) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/newforms/models.py in save_instance
instance.save() ...
/Users/leifstrickland/Sites/DjangoProject/mysite2/../mysite2/profile/
models.py in save
super(Profile, self).save()  ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/db/models/base.py in save
db_values + [pk_val]) ...
/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-
packages/django/db/backends/util.py in execute
return self.cursor.execute(sql, params) ...

---

In the last step, the local db_values var is a tuple of values to be
used in the DB query. All values are correct except for the
zip_code_id, which is None. That shouldn't be the case, because the
zip code field's clean() function has worked properly (i.e., returned
the corresponding zip_code_id) in shell and admin testing. So somehow
the value returned by the clean() function is being overwritten or
ignored later in the script. I just can't figure it out.

Thanks again for all the help.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread Jeremy Dunck

On 6/27/07, leif strickland <[EMAIL PROTECTED]> wrote:
...
> zip_code_id =
> Postal_Code.objects.get(postal_code=value).id

Is Postal_Code.postal_code a string or numeric?
...
> try:
> zip_code = Postal_Code.objects.get(id =
> value).postal_code
> except:
> zip_code = value

Again, you may want to str() .postal_code if it's numeric.

Are you registering your custom ModelAdmin with django.contrib.admin.site?

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

OK, I've been tinkering with this all day, and I'm still having one
big problem
As Jeremy suggested, I created custom ZipCodeField and MyAdmin
classes. In addition, I created a custom ZipcodeLookupInput widget.

I've tested this in the shell and on the test server, and the clean
and render functions appear to be working beautifully. The widget's
render() function looks up the initial value (the zip code id) and
uses the corresponding zip code as its display value, and the field's
clean() function converts the user-provided zip into an id and
returns
it as an integer value.

Unfortunately, I keep getting an error when I try to save. It appears
that the zip_code_id is None by the time a DB query is attempted in
django.db.backends.util. But this makes no sense, beacuse the clean()
function seems to be working properly (i.e., it returns an integer
value).

Does anyone know what might be happening?  I have pasted my custom
classes code below.

from mysite.address.models import Postal_Code
from django import newforms as forms

[...]

class ProfileOptions(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'zip_code':
return ZipCodeField(**kwargs)
else:
return
super(ProfileOptions,self).formfield_for_dbfield(db_field,
**kwargs)

class ZipCodeField(forms.fields.CharField):
def __init__(self, **kwargs):
kwargs['widget'] = ZCLookupTextInput
self.max_length, self.min_length = 5, 5
super(ZipCodeField, self).__init__(**kwargs)

def clean(self, value):
super(ZipCodeField, self).clean(value)
try:
zip_code_id =
Postal_Code.objects.get(postal_code=value).id
except Postal_Code.DoesNotExist:
raise ValidationError, "Please enter a valid
zip code."
return int(zip_code_id)

class ZCLookupTextInput(forms.widgets.TextInput):
def render(self, name, value, attrs=None):
try:
zip_code = Postal_Code.objects.get(id =
value).postal_code
except:
zip_code = value
return super(ZCLookupTextInput, self).render(name,
zip_code, attrs)



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif strickland

OK, I've been tinkering with this all day, and I'm still having one
big problem

As Jeremy suggested, I created custom ZipCodeField and MyAdmin
classes. In addition, I created a custom ZipcodeLookupInput widget.

I've tested this in the shell and on the test server, and the clean
and render functions appear to be working beautifully. The widget's
render() function looks up the initial value (the zip code id) and
uses the corresponding zip code as its display value, and the field's
clean() function converts the user-provided zip into an id and returns
it as an integer value.

Unfortunately, I keep getting an error when I try to save. It appears
that the zip_code_id is None by the time a DB query is attempted in
django.db.backends.util. But this makes no sense, beacuse the clean()
function seems to be working properly (i.e., it returns an integer
value).

Does anyone know what might be happening?  I have pasted my custom
classes code below.


from mysite.address.models import Postal_Code
from django import newforms as forms

[...]

class ProfileOptions(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'zip_code':
return ZipCodeField(**kwargs)
else:
return 
super(ProfileOptions,self).formfield_for_dbfield(db_field,
**kwargs)

class ZipCodeField(forms.fields.CharField):
def __init__(self, **kwargs):
kwargs['widget'] = ZCLookupTextInput
self.max_length, self.min_length = 5, 1
super(ZipCodeField, self).__init__(**kwargs)

def clean(self, value):
super(ZipCodeField, self).clean(value)
try:
zip_code_id = 
Postal_Code.objects.get(postal_code=value).id
except Postal_Code.DoesNotExist:
raise ValidationError, "Please enter a valid zip code."
return int(zip_code_id)


class ZCLookupTextInput(forms.widgets.TextInput):
def render(self, name, value, attrs=None):
try:
zip_code = Postal_Code.objects.get(id = 
value).postal_code
except:
zip_code = value
return super(LookupTextInput, self).render(name, zip_code, 
attrs)




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif

Great advice -- thanks! I'll work on it today and let you know how it
comes together.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread Jeremy Dunck

On 6/27/07, leif <[EMAIL PROTECTED]> wrote:
...
> Thanks for the input, Jeremy. I've actually decided to use newforms-
> admin since I won't be going to production for another few months

Sorry for missing that the first time.  :)

Admin uses django.newforms.models.form_for_model, which takes an
optional formfield_callback in order to map between DB fields and form
fields.

In order to supply that parameter, it looks like you'll need to
inherit from django.contrib.admin.options.ModelAdmin and override
formfield_for_dbfield.  That method maps between database fields and
form fields.

Have formfield_for_dbfield return your custom field class (a subclass
of django.newforms.fields.Field; CharField might make sense), then
override the Field.clean method to do your FK lookup and raise a
ValidationError if it's not a valid zip code.

NB: I haven't used newforms much myself yet.  Please report back if
you run into any troubles.  :)

You'll end up with something like this:


class MyAdmin(ModelAdmin):
   def formfield_for_dbfield(self, db_field, **kwargs):
  if isinstance(db_field, models.ForeignKey) and db_field.name ==
'zip_code':
 return ZipCodeField(**kwargs)
  else:
 super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)

---
class ZipCodeField(CharField):
def __init__(self, *args, **kwargs):
self.max_length, self.min_length = 5, 5
super(ZipCodeField, self).__init__(*args, **kwargs)

   def clean(self, value):
   value = super(ZipCodeField, self).clean(self, value)
   from yourmodels import ZipCode
   try:
  ZipCode.objects.get(pk=value)
   except ZipCode.DoesNotExist:
  raise ValidationError, "Please enter a valid zip code"
   return value

---
from django.contrib.admin import site
site.register(YourModel, YourAdminClass)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-27 Thread leif

> Django's existing admin uses oldforms.  The newforms-admin branch is
> working to rewrite admin to be more flexible and use newforms.  If you
> need it on trunk now, you'll need to use oldforms.

Thanks for the input, Jeremy. I've actually decided to use newforms-
admin since I won't be going to production for another few months (and
hopefully it will be incorporated into the trunk soon). Do you know
how I can attack the problem using that branch?


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-26 Thread Jeremy Dunck

On 6/26/07, leif <[EMAIL PROTECTED]> wrote:
> My main problem, though, is figuring out how to create a text input
> lookup field for the ZIP code foreign key.


> Do I need to code a new
> widget? A new form field class? A function to hook into newforms'
> validation?

> And if I create a widget or form field class, how to I coax Django
> into using it for the admin change and add pages?

Django's existing admin uses oldforms.  The newforms-admin branch is
working to rewrite admin to be more flexible and use newforms.  If you
need it on trunk now, you'll need to use oldforms.

You'll need to inherit from django.db.models.fields.Field and override
Field.get_manipulator_field_objs.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-26 Thread leif

Very good point, Tim. I'll consider that issue as I move forward with
my application.

My main problem, though, is figuring out how to create a text input
lookup field for the ZIP code foreign key. Do I need to code a new
widget? A new form field class? A function to hook into newforms'
validation?

And if I create a widget or form field class, how to I coax Django
into using it for the admin change and add pages?



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



Re: Zip code lookup field

2007-06-26 Thread Tim Chase

> My question, then, is this: What's the most elegant way to
> pull off this hack? By the way, I am using newforms and the
> newforms-admin branch. (I want my customizations to work with
> 1.0 and beyond.)

Generally, zip-codes and cities have a one-to-one correspondence.
 However, this isn't 100% the case.

You could offer a zip-entry and then, if ambiguity arose, allow
the user to choose the intended town to clarify, much like other
error/validation processes where you'd repopulate the screen with
the existing data but flag the ambiguity as an error condition.

It would also be helpful to given the user a preview anyways in
case they mis-typed their zip-code.

-tim



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---