问题
I have an Invoice master model and its admin. In the Invoice detail(Inline), I wish to select distinct products from Product table i.e In each Invoice detail, I should not allow to select product that has been previously selected. Can I get sample code for it? Relations defined: models.py:
class InvoiceHeader(models.Model): #model
number ....
class InvoiceDetail(models.Model):
header = models.ForeignKey(InvoiceHeader)
products = models.ManyToManyField(Product,related_field="products")
admin.py:
class InvoiceDetailForm(forms.ModelForm):
form = InvoiceDetailForm
def __init__(self, *args, **kwargs):
super(InvoiceDetailForm, self).__init__(*args, **kwargs)
# Below statement to be changed:
self.fields['products'].queryset = Product.objects.exclude(
name__exact=self.instance.invoicedetail.products.all()
class InvoiceDetailInline(admin.StackedInline):
extra = 1
class Meta:
model = InvoiceDetail
class InvoiceHeaderAdmin(admin.ModelAdmin):
class Meta:
model = InvoiceHeader
inlines = ['InvoceDetailInline']
Using django 1.6 only When I select a product A in InvoiceDetailInline, in its next Inline form I should not be able to select product A. Selection of product B should be allowed. Is tehre some javascript or jquery that I could use for this scenario. I will need the full detailed js as I am not good at it. Please revert ASAP and oblige
回答1:
The first answer was wrong as I misunderstood your question. I took my time to analyse your problem and came up with these files:
models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.name
class InvoiceHeader(models.Model):
number = models.IntegerField(unique=True)
def __str__(self):
return str(self.number)
class InvoiceDetail(models.Model):
header = models.ForeignKey(InvoiceHeader, related_name='invoicedetail')
products = models.ManyToManyField(
Product,
related_name='invoicedetail')
def __str__(self):
return '{0}, {1}'.format(self.header, self.products.all())
admin.py
from django.contrib import admin
from django.forms import ModelForm
from invoice.models import Product
from invoice.models import InvoiceHeader
from invoice.models import InvoiceDetail
class ProductAdmin(admin.ModelAdmin):
model = Product
class InvoiceDetailAdmin(admin.ModelAdmin):
model = InvoiceDetail
class InvoiceDetailInline(admin.StackedInline):
model = InvoiceDetail
extra = 1
class InvoiceHeaderAdmin(admin.ModelAdmin):
model = InvoiceHeader
inlines = [InvoiceDetailInline]
admin.site.register(Product, ProductAdmin)
admin.site.register(InvoiceDetail, InvoiceDetailAdmin)
admin.site.register(InvoiceHeader, InvoiceHeaderAdmin)
I tried to fill up the missing parts in my opinion. If you try these files, than you can add InvoiceHeader in the admin area with an inline select box for InvoiceDetail. You can press "Add another Invoice Detail" for another inline select box and so on. And here you don't want to select the same product for the same invoice header number. Did I understand you right?
Let's say you have the following invoice headers:
- 12345
- 23456
- 34567
and the following products:
- keyboard
- mouse
- speakers
- headset
- webcam
Than you could make the following invoice details:
- 12345, keyboard, mouse
- 12345, speakers
- 23456, speakers, headset, webcam
- 34567, keyboard, mouse
- 34567, headset, webcam
but the following should not be possible:
- 12345, keyboard, mouse
- 12345, keyboard, speakers // keyboard already chosen
- 23456, speakers
- 23456, mouse, speakers // speakers already chosen
I hope that my assumption is right.
So in the inline select box in the admin area you would be still able to select the products, but you could write your own validation rules that would prevent saving.
Maybe I can give you some further suggestions. It would be good if you can confirm that my example fits so far.
来源:https://stackoverflow.com/questions/25033137/select-unselected-m2m-instance-in-django-model-form