开发者

Setting a preferred item of a many-to-one in Django

开发者 https://www.devze.com 2022-12-22 13:21 出处:网络
I\'m trying to create a Django model that handles the following: An Item can have several Names. One of the Names for an Item is its primary Name, i.e. the Name displayed given an Item.

I'm trying to create a Django model that handles the following:

  • An Item can have several Names.
  • One of the Names for an Item is its primary Name, i.e. the Name displayed given an Item.

(The model names were changed to protect the innocent.)

The models.py I've got looks like:开发者_如何转开发

class Item(models.Model):
    primaryName = models.OneToOneField("Name", verbose_name="Primary Name", 
        related_name="_unused")
    def __unicode__(self):
        return self.primaryName.name

class Name(models.Model):
    item = models.ForeignKey(Item)
    name = models.CharField(max_length=32, unique=True)
    def __unicode__(self):
        return self.name

class Meta: ordering = [ 'name' ]

The admin.py looks like:

class NameInline(admin.TabularInline):
    model = Name

class ItemAdmin(admin.ModelAdmin):
    inlines = [ NameInline ]

admin.site.register(Item, ItemAdmin)

It looks like the database schema is working fine, but I'm having trouble with the admin, so I'm not sure of anything at this point. My main questions are:

  • How do I explain to the admin that primaryName needs to be one of the Names of the item being edited?
  • Is there a way to automatically set primaryName to the first Name found, if primaryName is not set, since I'm using inline admin for the names?

EDIT: Dang, I forgot this was still open. Anyway, I wound up redoing the model, replacing primaryName with just name (a CharField) in Item and renaming Name to Alias. This can't do what I wanted to (just search one table for a name), but I couldn't make the primaryName work if it didn't have null=True, since Item gets saved before any Names were created, meaning that any attempt to auto-assign a Name would see an empty QuerySet and fail.

The only way I could see it working was to have Name's save routine auto-set itself as its parent's primaryName if primaryName was NULL, which just didn't sit well with me.


i think you will want to take a look here.

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin

define your own form to take care of any custom validation that might be required.


  • How do I explain to the admin that primaryName needs to be one of the Names of the item being edited?

Check out formfield_for_foreignkey() in the ModelAdmin docs.

class ItemAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "primaryName":
            # tweak the filter to your liking.
            kwargs["queryset"] = Name.objects.filter(item=...)
            return db_field.formfield(**kwargs)
        return super(ItemAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)


  • Is there a way to automatically set primaryName to the first Name found, if primaryName is not set, since I'm using inline admin for the names?

You could do this in your model's save method, something like:

class Item(models.Model):
    ...(snip)...
    def save(self,force_insert=False,force_update=False):
        if self.primaryName is None:
            self.primaryName = self.name_set.all()[0]
            # will want to handle the case that no names are set, etc
        super(Item,self).save(force_insert,force_update)
0

精彩评论

暂无评论...
验证码 换一张
取 消