Opened 19 years ago

Closed 16 years ago

#565 closed defect (fixed)

Unique fields don't work on edit_inline models

Reported by: kyrrigle@… 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 david@…, 19 years ago

Keywords: admin edit inline unique error added
Version: magic-removal

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

  1. response = callback(request, *callback_args, callback_kwargs)

File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/decorators.py" in _checklogin

  1. return view_func(request, *args, kwargs)

File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/views/decorators/cache.py" in _wrapped_view_func

  1. response = view_func(request, *args, kwargs)

File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/contrib/admin/views/main.py" in change_stage

  1. new_object = manipulator.save(new_data)

File "/usr/lib/python2.4/site-packages/Django-0.91-py2.4.egg/django/db/models/manipulators.py" in save

  1. if rel_new_data[related.opts.pk.name][0]:

KeyError at /admin/trak/hardware/3/
'id'

I can edit any of these models individually, but when edited "inline" I get the above error.

comment:2 by david@…, 19 years ago

Disregard my previous addendum to this ticket. The error I described has nothing to do with this.

comment:3 by anonymous, 18 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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 Seer, 18 years ago

Summary: Unique fields don't work on edit_inline modelsUnique fields don''t work on edit_inline models

Hi all
im fine, gl all!

comment:5 by Simon G. <dev@…>, 18 years ago

Triage Stage: UnreviewedAccepted
Version: magic-removalSVN

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 Simon G. <dev@…>, 18 years ago

Summary: Unique fields don''t work on edit_inline modelsUnique fields don't work on edit_inline models

comment:7 by Emanuele Pucciarelli <ep@…>, 17 years ago

Cc: ep@… added

comment:8 by kent37@…, 17 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 anonymous, 17 years ago

Cc: christoph.rauch@… added

comment:10 by anonymous, 17 years ago

Cc: frankie@… added

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

I've marked #5302, #526, #2470, #2641, #4639, #4490 as duplicates of this.

comment:12 by Jan Oberst <mail@…>, 17 years ago

Cc: mail@… added

comment:13 by Jarek Zgoda, 17 years ago

Cc: jarek.zgoda@… added

comment:14 by anonymous, 17 years ago

Cc: avinash@… added

comment:15 by Kent Johnson <kent37@…>, 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 Jason Green <Django@…>, 17 years ago

Cc: Django565@… added

comment:17 by Matias Surdi <matiassurdi@…>, 17 years ago

Cc: matiassurdi@… added

comment:18 by duke@…, 16 years ago

Cc: duke@… 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 mrts, 16 years ago

Keywords: nfa-fixed added

comment:20 by Brian Rosner, 16 years ago

Resolution: fixed
Status: newclosed

This is no longer a problem since the merge of newforms-admin in [7967].

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