Opened 18 years ago

Closed 17 years ago

#2641 closed defect (duplicate)

Having a "unique" field inside a Model with a ForeignKey breaks the admin UI

Reported by: terry@… Owned by: Adrian Holovaty
Component: contrib.admin Version: dev
Severity: normal Keywords:
Cc: jshaffer2112@…, frankie@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


The below model breaks in the admin UI:

class Store(models.Model): 
2	    lastupdate = models.DateTimeField(auto_now=True) 
3	    name = models.CharField(maxlength=255) 
4	    address = models.CharField(maxlength=255) 
5	    city = models.CharField(maxlength=255) 
6	    usstate = models.USStateField() 
7	    zip = models.CharField(maxlength=255) 
8	    class Admin: 
9	        pass 
12	class StorePhone(models.Model): 
13	    lastupdate = models.DateTimeField(auto_now=True) 
14	    store = models.ForeignKey(Store, 
15	                              edit_inline=models.TABULAR, 
16	                              num_in_admin = 3) 
17	    phonenum = models.PhoneNumberField(core=True, db_index=True, unique=True) 
18	    phonetype = models.IntegerField(core=True, choices = ( 
19	            (1, "DNIs"), 
20	            (2, "Forwarded 800 #"), 
21	            )) 

Trying to create a new Store results in this error:

File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/core/handlers/" in get_response 
27	  74. response = callback(request, *callback_args, **callback_kwargs) 
28	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/contrib/admin/views/" in _checklogin 
29	  55. return view_func(request, *args, **kwargs) 
30	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/views/decorators/" in _wrapped_view_func 
31	  39. response = view_func(request, *args, **kwargs) 
32	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/contrib/admin/views/" in add_stage 
33	  250. errors = manipulator.get_validation_errors(new_data) 
34	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/forms/" in get_validation_errors 
35	  58. errors.update(field.get_validation_errors(new_data)) 
36	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/forms/" in get_validation_errors 
37	  351. self.run_validator(new_data, validator) 
38	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/forms/" in run_validator 
39	  341. validator(new_data.get(self.field_name, ''), new_data) 
40	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/fields/" in manipulator_validator_unique 
41	  35. old_obj = self.manager.get(**{lookup_type: field_data}) 
42	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in get 
43	  67. return self.get_query_set().get(*args, **kwargs) 
44	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in get 
45	  211. obj_list = list(clone) 
46	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in __iter__ 
47	  103. return iter(self._get_data()) 
48	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in _get_data 
49	  430. self._result_cache = list(self.iterator()) 
50	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in iterator 
51	  171. select, sql, params = self._get_sql_clause() 
52	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in _get_sql_clause 
53	  444. joins2, where2, params2 = self._filters.get_sql(opts) 
54	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in get_sql 
55	  574. joins2, where2, params2 = val.get_sql(opts) 
56	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in get_sql 
57	  622. return parse_lookup(self.kwargs.items(), opts) 
58	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in parse_lookup 
59	  734. joins2, where2, params2 = lookup_inner(path, lookup_type, value, opts, opts.db_table, None) 
60	File "/Library/Python/2.3/site-packages/Django-0.95-py2.3.egg/django/db/models/" in lookup_inner 
61	  835. raise TypeError, "Cannot resolve keyword '%s' into field" % name 
63	  TypeError at /admin/order/store/add/ 
64	  Cannot resolve keyword 'phonenum' into field 

If you remove the "unique" part of the phonenum field, it gets much happier.

I can sort of understand. I want it to be illegal for you to assign a phone number to a store if that same number is already assigned to another store. But I can understand that the admin code doesn't get that. And that it is getting confused by the "unique" thing, when it already thinks it has a unique thing.

But it's still a bug. At the very least, I ought to get a more useful error message somewhere.

Change History (8)

comment:1 by Gary Wilson <gary.wilson@…>, 18 years ago

This could be related to or a duplicate of #1751.

comment:2 by Ville Säävuori <Ville@…>, 17 years ago

This just bit me. I think it only appears when the object is edited inline.

comment:3 by taavi223@…, 17 years ago

I'll confirm that this is only an issue when you edit the object inline on another model's page.

comment:4 by Chris Beaven, 17 years ago

Triage Stage: UnreviewedAccepted

Seems like it's a valid bug then.

comment:5 by John Shaffer <jshaffer2112@…>, 17 years ago

Cc: jshaffer2112@… added
Version: 0.95SVN

This isn't a duplicate of #1751.

The cause is described at

comment:6 by John Shaffer <jshaffer2112@…>, 17 years ago

The root of this problem is in django/db/models/fields/ When manipulator_validator_unique() is curried with a manipulator at line 250 (in 0.96 release), the manipulator.manager is the manager for the related model (the model being edited), not the model containing the ForeignKey. So the call to self.manager.get() in manipulator_validator_unique() (line 37) looks up the unique field in the wrong table.

comment:7 by anonymous, 17 years ago

Cc: frankie@… added

comment:8 by Simon G. <dev@…>, 17 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #565

Note: See TracTickets for help on using tickets.
Back to Top