Reputation: 21136
In the following model (Item
) my goal is to define a customized object ID explicitly when saving. I'm using Django 1.2.5 and sqlite.
class Category(models.Model):
name = models.CharField(max_length=32)
class Item(models.Model):
id = models.CharField(primary_key=True, blank=True, max_length=8)
group = models.ForeignKey(Category)
def save(self, *args, **kwargs):
self.id = "%s-%s" % (self.group.id, self.group.item_set.count() + 1)
super(Item, self).save(*args, **kwargs)
I have the problem that using the admin interface for Item model, when I'm going to save an object that already exists, instead of update the existing record a new record is created. I tried to force the update when appropriate with this code
def save(self, *args, **kwargs):
update = bool(self.id)
self.id = "%s-%s" % (self.group.id, self.group.item_set.count() + 1)
super(Item, self).save(force_update=update, *args, **kwargs)
but without success. Now saving after a change triggers this other problem:
DatabaseError at /admin/type/catalog/1_3/
Forced update did not affect any rows.
I'd like to know what I'm doing wrong and if there is a way to solve the issue.
Thanks
-- EDIT -- (need more help!)
Use case.
I want to obtain that when a category is selected, only the items that belongs to that category are shown in the items select box.
For this reason I need to associate each item to the corresponding category using the id field, so that categories and items in the admin interface, if together in the same page, would be relationated by their id (and thus easily handled using jQuery). This way:
<select id="id_category" name="category">
<option value="1">color</option>
<option value="2">car</option>
</select>
<select id="id_item" name="item">
<option value="1_1">red</option>
<option value="1_2">blue</option>
<option value="2_1">audi</option>
</select>
If I would use another field but id, combobox in admin would be totally unrelated in respecet if their id, because item select would be:
<option value="1">red</option>
<option value="2">blue</option>
<option value="3">audi</option>
Hope I've been clear enough!
Upvotes: 0
Views: 1960
Reputation: 39307
This isn't a direct answer to your question, but you might want to leave your id field and instead add a category_id field instead.
from django.db.models import Max
class Category(models.Model):
name = models.CharField(max_length=32)
class Item(models.Model):
cat_id = models.IntegerField(editable=False, blank=True, null=True)
group = models.ForeignKey(Category)
class Meta:
unique_together = ('cat_id', 'group')
def save(self, *args, **kwargs):
self.cat_id = Items.objects.filter(group=self.group).aggregate(Max('cat_id'))['cat_id__max']+1
super(Item, self).save(*args, **kwargs)
Upvotes: 1