Select unselected m2m instance in django model form

北战南征 提交于 2019-12-10 11:48:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!