jazzband / django-smart-selects

chained and grouped selects for django forms
https://django-smart-selects.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.11k stars 348 forks source link

django-smart-select with django-material #232

Closed wynandvdl closed 6 years ago

wynandvdl commented 6 years ago

Hi

I had a look at issue #170 and have the same problem. I tried the workaround that was suggested, but unfortunately it does not work on the admin side. Everything works perfectly when django-material is disabled. I know the bug is not on your side, but it would be great if smart-selects would be able to work with django-material. Any help would be appreciated

Here is my model, the referenced foreignkey is in a different app and like I said smart-selects works without django-material enabled.

class Stock(models.Model):
    StockNumber = models.CharField(max_length=20, blank=True)
    MMCode = models.ForeignKey('mead.VehicleMM', related_name='vehicle')
    Year = ChainedForeignKey('mead.VehicleValue', chained_field="MMCode", chained_model_field="MMCode", show_all=False, auto_choose=True, sort=True)
    EngineNumber = models.CharField(max_length=50, verbose_name='Engine Number')
    VINNumber = models.CharField(max_length=50, verbose_name='VIN Number')
    RegistrationNumber = models.CharField(max_length=50, verbose_name='Registration Number')
    Colour = models.CharField(max_length=50)
    Mileage = models.IntegerField()
    FuelType = models.CharField(max_length=2, choices=FUEL_CHOICES, verbose_name='Fuel Type')
    NonFactoryAccessories = models.TextField(blank=True, verbose_name='Non Factory Accessories')
    PurchasePrice = models.DecimalField(max_digits=20, decimal_places=2)
    PaymentRemittanceNumber = models.CharField(max_length=100, blank=True, verbose_name='Payment Remittance Number')
    From = models.CharField(max_length=100, verbose_name='Vehicle Bought From')
    RetailValue = models.DecimalField(max_digits=20, decimal_places=2, null=True)
    ProfitMargin = models.DecimalField(max_digits=20, decimal_places=2, null=True)
    PurchaseDate = models.DateField()
    StandInValue = models.DecimalField(max_digits=20, decimal_places=2, null=True)
    NumberOfStockDays = models.IntegerField(null=True, verbose_name='Number of days in stock')
    SpareKeys = models.BooleanField(default=False)
    TrackingInstalled = models.BooleanField(default=False)
    SpareWheel = models.BooleanField(default=False)
    Jack = models.BooleanField(default=False)
    Tools = models.BooleanField(default=False)
    ServiceBooks = models.CharField(max_length=2, choices=SERVICE_CHOICES)
    Natis = models.FileField(upload_to='natis')
    LicenseRenewalDate = models.DateField()
    ServiceIntervals = models.CharField(max_length=100)
    NextServiceDueDate = models.DateField()
    NextServiceDueMileage = models.IntegerField()
    Status = models.CharField(max_length=2, choices=STATUS_CHOICES)

admin.py

class StockAdminForm(forms.ModelForm):
    class Meta:
        model = Stock
        widgets = {'Year': YearWidget(attrs={'to_app_name': 'stock',
                                            'to_model_name': 'Stock',
                                            'chained_field': 'MMCode',
                                            'chained_model_field': 'MMCode',
                                            'foreign_key_app_name': 'mead',
                                            'foreign_key_model_name': 'VehicleValue',
                                            'foreign_key_field_name': 'MMCode',
                                            'show_all': False,
                                            'auto_choose': True})}

@admin.register(Stock)
class StockAdmin(admin.ModelAdmin):
    list_display = ['StockNumber', 'Status']
    list_filter = ['Status',]
    search_fields = ['StockNumber',]
    raw_id_fields = ['MMCode',]
    form = StockAdminForm

widget.py as suggested workaround

from smart_selects.widgets import ChainedSelect

class YearWidget(ChainedSelect):
    def __init__(self, *args, attrs=None, **kwargs):
        self.attrs = attrs
        super(YearWidget, self).__init__(*args, **kwargs)

    def render(self, *args, **kwargs):
        super(YearWidget, self).render(*args, attrs=self.attrs, **kwargs)

The error I receive from shell

TypeError: init() missing 9 required positional arguments: 'to_app_name', 'to_model_name', 'chained_field', 'chained_model_field', 'foreign_key_app_name', 'foreign_key_model_name', 'foreign_key_field_name', 'show_all', and 'auto_choose'

pablovg2 commented 6 years ago

I have tested it and I get the same error.

Could you solve it?

dvb7836 commented 6 years ago

I have the same problem: /smart_selects/widgets.py in render, line 242 'NoneType' object does not support item assignment

{% admin_related_field_urls bound_field as bound_field_urls %}

brayan15 commented 6 years ago

I have the same problem anyone could solve it it?

blag commented 6 years ago

I don't want to complicate the code in django-smart-selects any more than it already is (it's brittle enough already), so I will not be fixing this.

The proper fix is to get django-material to properly render widgets as I noted in my comment on #170.

Sorry!

maldhureakshay commented 5 years ago

Here is the solution https://stackoverflow.com/a/52361037/3472881