django admin how to limit selectbox values
model:
class Store(models.Model):
name = models.CharField(max_length = 20)
class Admin:
pass
def __unicode__(self):
return self.name
class Stock(Store):
products = models.ManyToManyField(Product)
class Admin:
pass
def __unicode__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length = 128, unique = True)
parent = models.ForeignKey('self', null = True, blank = True, related_name='children')
(...)
def __unicode__(self):
return self.name
mptt.register(Product, order_insertion_by = ['name'])
admin.py:
from bar.drinkstore.models import Store, Stock
from django.contrib import admin
admin.site.register(Store)
admin.site.register(Stock)
Now when I look at admin site I can select any product from the list. But I'd like to have a limited choice - only leaves. In mptt class there's function:
is_leaf_node() -- returns True if the model instance is a leaf node (it has no children), False otherwise.
But I have no idea how to connect it
I'm trying to make a subclass: in admin.py:
from bar.drinkstore.models import Store, Stock
from django.contrib import admin
admin.site.register(Store)
class StockAdmin(admin.ModelAdmin):
def queryset(self, request):
return super(StockAdmin, self).queryset(request).filter(ihavenoideawhatfilter)
admin.site.register(S开发者_如何学运维tock, StockAdmin)
but I'm not sure if it's right way, and what filter set.
UPD: This is definetely wrong way. the queryset in class StockAdmin produces list of stocks. But I need to filter product list "on stock" - still don't know how.
Edit: Completely updated this
So the queryset, is finally ok but you need to filter the products on the Stock page select box (I guess?). You can define a custom form for the Stock ModelAdmin.
class StockForm(ModelForm):
products = forms.ModelChoiceField(queryset=Products.objects.filter(lft=F('rght')-1))
class Meta:
model = Stock
class StockAdmin(admin.ModelAdmin):
form = StockForm
Botondus has the right idea, but you can't do that with annotate
- that's for aggregations across related querysets. Try using extra
instead:
qs = super(StockAdmin, self).queryset(request).extra(
select={ 'desc_count': '(rght-lft-1)/2' }
).filter(desc_count=0)
So far your idea is right, I'm no expert on how to filter this correctly, but if you look at mptt.models.get_descendant_count
you see how the number of descendents i calculated, the leaves are those where the count is zero. I guess you will have to make this condition into raw sql!
EDIT: I just read the title of your question again right now, is it now about seectbox values or changing the queryset for the change list?
精彩评论