Opened 19 years ago
Closed 16 years ago
#565 closed defect (fixed)
Unique fields don't work on edit_inline models
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | normal | Keywords: | admin edit inline unique error nfa-fixed |
Cc: | kyrrigle@…, ep@…, christoph.rauch@…, frankie@…, mail@…, jarek.zgoda@…, avinash@…, Django565@…, matiassurdi@…, duke@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
There seems to be a bug with validating inline editable items that have unique=true.
To reproduce:
1) Modify the tutorial polls app so that the Choice model defines choice as:
choice = meta.CharField(maxlength=200, core=True, unique=True)
2) Create a poll with two choices, click 'save and continue editing'
3) Add a third choice (with unique name) and click 'save'
You should see a "Choice with this choice already exists." validation error for the second choice.
Change History (20)
comment:1 by , 19 years ago
Keywords: | admin edit inline unique error added |
---|---|
Version: | → magic-removal |
comment:2 by , 19 years ago
Disregard my previous addendum to this ticket. The error I described has nothing to do with this.
comment:3 by , 19 years ago
Similar goes here:
SVN: rev. 3002 (MR)
from django.db import models
class Customer( models.Model ):
name = models.CharField( maxlength=20, blank=False, unique=True )
def str( self ):
return self.name
class Admin:
pass
class Komputer( models.Model ):
Customer = models.ForeignKey( Customer, edit_inline=models.TABULAR, num_in_admin=1)
hwaddr = models.CharField( maxlength=17, unique=True, core=True )
def str(self):
return self.hwaddr
class Admin:
pass
Adding new Customer(and Komputer)... when added individually no problem occurs
Traceback (most recent call last):
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/core/handlers/base.py" in get_response
- response = callback(request, *callback_args, callback_kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/decorators.py" in _checklogin
- return view_func(request, *args, kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/views/decorators/cache.py" in _wrapped_view_func
- response = view_func(request, *args, kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/main.py" in add_stage
- errors = manipulator.get_validation_errors(new_data)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/forms/init.py" in get_validation_errors
- errors.update(field.get_validation_errors(new_data))
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/forms/init.py" in get_validation_errors
- self.run_validator(new_data, validator)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/forms/init.py" in run_validator
- validator(new_data.get(self.field_name, ), new_data)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/fields/init.py" in manipulator_validator_unique
- old_obj = self.manager.get({lookup_type: field_data})
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/manager.py" in get
- return self.get_query_set().get(*args, kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in get
- obj_list = list(clone)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in iter
- return iter(self._get_data())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in _get_data
- self._result_cache = list(self.iterator())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in iterator
- select, sql, params = self._get_sql_clause()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in _get_sql_clause
- tables2, joins2, where2, params2 = self._filters.get_sql(opts)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in get_sql
- tables2, joins2, where2, params2 = val.get_sql(opts)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in get_sql
- return parse_lookup(self.kwargs.items(), opts)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in parse_lookup
- tables2, joins2, where2, params2 = lookup_inner(path, clause, value, opts, opts.db_table, None)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/query.py" in lookup_inner
- raise TypeError, "Cannot resolve keyword '%s' into field" % name
TypeError at /admin/siec/customer/add/
Cannot resolve keyword 'hwaddr' into field
sqlite ver. 3.3.4
comment:4 by , 18 years ago
Summary: | Unique fields don't work on edit_inline models → Unique fields don''t work on edit_inline models |
---|
Hi all
im fine, gl all!
comment:5 by , 18 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | magic-removal → SVN |
I've replicated this with the current SVN and this model:
from django.db import models # Create your models here. class Poll(models.Model): question = models.CharField(maxlength=200) pub_date = models.DateTimeField('date published') class Admin: pass class Choice(models.Model): poll = models.ForeignKey(Poll, edit_inline=models.STACKED, num_in_admin=3) choice = models.CharField(maxlength=200, core=True, unique=True) votes = models.IntegerField(core=True) class Admin: pass
However, it raises an IntegrityError (column choice is not unique) and not just a warning.
comment:6 by , 18 years ago
Summary: | Unique fields don''t work on edit_inline models → Unique fields don't work on edit_inline models |
---|
comment:7 by , 18 years ago
Cc: | added |
---|
comment:8 by , 18 years ago
The root of this problem is in django/db/models/fields/__init__.py
. 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:9 by , 17 years ago
Cc: | added |
---|
comment:10 by , 17 years ago
Cc: | added |
---|
comment:11 by , 17 years ago
comment:12 by , 17 years ago
Cc: | added |
---|
comment:13 by , 17 years ago
Cc: | added |
---|
comment:14 by , 17 years ago
Cc: | added |
---|
comment:15 by , 17 years ago
There is a similar problem using unique_together
in a model that is edited inline in another model's admin interface. This causes an AttributeError, e.g. unique_together = (('person', 'blog', 'role'),)
causes this error:
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/django/db/models/fields/__init__.py" in get_manipulator_fields 240. params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list))) AttributeError at /admin/stats/blog/1262/ 'ChangeManipulator' object has no attribute 'isUniqueperson_blog_role'
comment:16 by , 17 years ago
Cc: | added |
---|
comment:17 by , 17 years ago
Cc: | added |
---|
comment:18 by , 17 years ago
Cc: | added |
---|
Some comments in a couple duplicates (#526 and #2470) point out that order matters in unique_together. Apparently the related field must appear first in the list of fields. This approach works for me.
I just thought I'd repeat that information here for anyone who ends up on this bug looking for a solution.
comment:19 by , 16 years ago
Keywords: | nfa-fixed added |
---|
comment:20 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
This is no longer a problem since the merge of newforms-admin in [7967].
This seems to apply to models that don't themselves contain a unique field but references a model that does.
For example, I've got a model NetworkAddressMap that relates 3 separate models: NetworkIpAddress, NetworkMacAddress, and Hardware. NetworkAddressMap has foreign keys for all of these models, and the one that points to Hardware specifies edit_inline=models.TABULAR. With this setup, I can add entries from the Hardware interface, but when I attempt to edit it after saving, I get this error:
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/core/handlers/base.py" in get_response
File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/decorators.py" in _checklogin
File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/views/decorators/cache.py" in _wrapped_view_func
File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/main.py" in change_stage
File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/manipulators.py" in save
I can edit any of these models individually, but when edited "inline" I get the above error.