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.1k stars 348 forks source link

Multiple chained selects being cleared out after page refresh. Only first one in chain retains value. #292

Closed matthewjennings73 closed 4 years ago

matthewjennings73 commented 4 years ago

You MUST use this template when reporting issues. Please make sure you follow the checklist and fill in all of the information sections below.


All versions of django-smart-selects prior to version 1.2.8 are vulnerable to an XSS attack as detailed in issue 171. As a result, all previous versions have been removed from PyPI to prevent users from installing insecure versions. All users are urged to upgrade as soon as possible.

Checklist

Put an x in the bracket when you have completed each task, like this: [x]

Steps to reproduce

  1. All installed and working perfect.
  2. Choices are saved to database
  3. When change form is reloaded all chained selects are loaded from database but then they all reset except the first one.

Using django-smart-selects 1.5.4 (js-unlining-fixes; Master didn't work as expected)

Actual behavior

image

Expected behavior

image

matthewjennings73 commented 4 years ago

Basically it loads all the dropdowns from the database during the reload and you can actually see them for a second. Then Country through City get returned to their initial empty_label values. If you use Inspection on those dropdowns they do show the correct values. In the form above, Region is simply a foreignkey field that serves as the start of the chaining that begins with subregion through city.

matthewjennings73 commented 4 years ago

Their 'data-value' tags are set correctly for each dropdown (when using Chrome inspect) , but what shows is the empty-value. I've also noticed that when I removed the ajax script for jquery.min.js they all load as expected, but then the triggers obviously don't work and then django-smart-selects functionality doesn't work. I've tried several different version of 'jquery.min.js' and all have the same output so I doubt that's the problem. Is there an option I'm missing that could fix this?

matthewjennings73 commented 4 years ago

Here are my models:

class LocationRegion(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the region name')

    class Meta:
        managed = False
        db_table = 'location_region'

    def __str__(self):
        return str(self.name)

class LocationSubregion(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the subregion name')
    region = models.ForeignKey(LocationRegion,  null=False, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'location_subregion'

    def __str__(self):
        return str(self.name)

class LocationCountry(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the country name')
    subregion = models.ForeignKey(LocationSubregion, null=False, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'location_country'
        verbose_name_plural = 'Location countries'

    def __str__(self):
        return str(self.name)

class LocationState(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the state/province name')
    country = models.ForeignKey(LocationCountry, null=False, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'location_state'

    def __str__(self):
        return str(self.name)

class LocationCounty(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the county/parish name')
    state = models.ForeignKey(LocationState, null=False, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'location_county'
        verbose_name_plural = 'Location counties'

    def __str__(self):
        return str(self.name)

class LocationCity(models.Model):
    name = models.CharField(max_length=255, null=False, help_text='Please enter the city/town name')
    county = models.ForeignKey(LocationCounty, null=False, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'location_city'
        verbose_name_plural = 'Location Cities'

    def __str__(self):
        return str(self.name)

and here is the model that brings all the chainedforeignkeys together.

class Project(models.Model):
    name = models.CharField(max_length=255, null=False)
    address_line_1 = models.CharField(max_length=100, blank=True, null=True,
                                      help_text='Street address, P.O. box, etc.')
    address_line_2 = models.CharField(max_length=100, blank=True, null=True,
                                      help_text='Suite, unit, building, floor, etc.')
    region = models.ForeignKey(LocationRegion, models.DO_NOTHING, null=False, help_text='Choose a region')
    subregion = ChainedForeignKey(
        LocationSubregion,
        related_name='subregion',
        chained_field='region',
        chained_model_field='region',
        show_all=False,
        auto_choose=True,
        sort=True,
        help_text='Choose a subregion',
    )
    country = ChainedForeignKey(
        LocationCountry,
        related_name='country',
        chained_field='subregion',
        chained_model_field='subregion',
        show_all=False,
        auto_choose=True,
        sort=True,
        help_text='Choose a country',
    )
    state = ChainedForeignKey(
        LocationState,
        blank=True, null=True,
        related_name='state',
        chained_field='country',
        chained_model_field='country',
        show_all=False,
        auto_choose=True,
        sort=True,
        help_text='Choose a state',
    )
    county = ChainedForeignKey(
        LocationCounty,
        blank=True, null=True,
        related_name='county',
        chained_field='state',
        chained_model_field='state',
        show_all=False,
        auto_choose=True,
        sort=True,
        help_text='Choose a county',
    )
    city = ChainedForeignKey(
        LocationCity,
        blank=True, null=True,
        related_name='city',
        chained_field='county',
        chained_model_field='county',
        show_all=False,
        auto_choose=True,
        sort=True,
        help_text='Choose a city'
    )
    zip_code = models.CharField(max_length=100, blank=True, null=True, help_text='Please enter a zip or postal code')

    class Meta:
        managed = False
        db_table = 'project'

    def __str__(self):
        return self.name
matthewjennings73 commented 4 years ago

Here are my url.py patterns:

urlpatterns = [
    (url(r'^', include(admin.site.urls)) if django.VERSION < (2, 0)
     else url(r'^', admin.site.urls)),
    url(r'^chaining/', include('smart_selects.urls')),
]

And here are my scripts for my Base file:

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
{% compress js %}
    <script src="{% static 'admin/bootstrap-4.3.1/js/dist/util.js' %}" type="text/javascript" charset="utf-8"></script>
    <script src="{% static 'admin/bootstrap-4.3.1/js/dist/dropdown.js' %}" type="text/javascript" charset="utf-8"></script>
    <script src="{% static 'admin/bootstrap-4.3.1/js/dist/collapse.js' %}" type="text/javascript" charset="utf-8"></script>
    <!-- Smart select -->
    <script src="{% static 'smart-selects/admin/js/bindfields.js' %}" type="text/javascript" charset="utf-8"></script>
    <script src="{% static 'smart-selects/admin/js/chainedfk.js' %}" type="text/javascript" charset="utf-8"></script>
    <script src="{% static 'smart-selects/admin/js/chainedm2m.js' %}" type="text/javascript" charset="utf-8"></script>
{% endcompress %}

And finally here are my jquery entries in settings.py:

USE_DJANGO_JQUERY = True
JQUERY_URL = False
matthewjennings73 commented 4 years ago

Is anyone monitoring questions here...curious why this is getting ignored?

manelclos commented 4 years ago

@matthewjennings73 the package is being transitioned to jazzband, and that is taking time. I did some work to fix it so it works for us, here: https://github.com/jazzband/django-smart-selects/commits/issue-253-chainedfk-is-not-defined

Please let me know if you try that branch.

matthewjennings73 commented 4 years ago

Great thanks for the reply. Will give it a go and let you know!

matthewjennings73 commented 4 years ago

Yeah I tried that and still getting same behavior.

matthewjennings73 commented 4 years ago

Are there any example of multiple chained selects using this package? Like I said, the first one works, but then then everything after doesn't seem to repopulate?

manelclos commented 4 years ago

Hi @matthewjennings73,

I added another chained select to Location in the test_app and it works ok here. You can check the changes on the same issue-253 branch.

Please check that you are not running into browser cache issues when trying issue-253 branch.

You can try the test_app example using:

python manage.py migrate
python manage.py loaddata test_app/fixtures/*
python manage.py runserver

Then login with admin/admin at http://127.0.0.1:8000/admin/

image

Hope this helps :)

matthewjennings73 commented 4 years ago

Checking to see if this will resolve my issues.

matthewjennings73 commented 4 years ago

Still not solving my issues. My selections still appear and then disappear during the refresh of the change_form. It seems like there is something in jquery that is causing this. I have tried so many things to correct this, but it doesn't seem to fix the issue....very happy to donate to the development of this to get this working!

manelclos commented 4 years ago

@matthewjennings73 isn't the test app working for you?

nanliao-yzh commented 4 years ago

I also have this problem. It's not normal in chrome, but it's good in safari

manelclos commented 4 years ago

@shishinanliao did you try the test described in this issue?

nanliao-yzh commented 4 years ago

@shishinanliao您是否尝试过本期中介绍的测试?

Yes, I have

manelclos commented 4 years ago

Can someone reproduce the problem using the test app provided in django-smart-selects?

manelclos commented 4 years ago

I just tested Django 3.0 and this works as expected in the test app (http://localhost:9000/admin/test_app/location/1/change/).

Could you please add more details? is the console showing any Javascript error?

matthewjennings73 commented 4 years ago

Upgraded to Django 3.0 and added the changes from above and still same behavior and no erros in javascript in console in google inspection.

matthewjennings73 commented 4 years ago

I am getting this now in conosle in pycharm which shows me the right data is getting to each field...it's just somehow being set back to blank...

[27/Apr/2020 12:54:40] "GET /chaining/filter/datasets/LocationSubregion/region/datasets/ProjectLocation/subregion/1/ HTTP/1.1" 200 166
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCountry/subregion/datasets/ProjectLocation/country/1/ HTTP/1.1" 200 77
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationState/country/datasets/ProjectLocation/state/2/ HTTP/1.1" 200 1963
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCounty/state/datasets/ProjectLocation/county/2/ HTTP/1.1" 200 2514
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCity/county/datasets/ProjectLocation/city/63/ HTTP/1.1" 200 77
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCountry/subregion/datasets/ProjectLocation/country/1/ HTTP/1.1" 200 77
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationState/country/datasets/ProjectLocation/state/2/ HTTP/1.1" 200 1963
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCounty/state/datasets/ProjectLocation/county/2/ HTTP/1.1" 200 2514
[27/Apr/2020 12:54:41] "GET /chaining/filter/datasets/LocationCity/county/datasets/ProjectLocation/city/63/ HTTP/1.1" 200 77
matthewjennings73 commented 4 years ago

So it worked in Explorer but not in chrome now? Same as @shishinanliao. ANy ideas how to fix that?

matthewjennings73 commented 4 years ago

Okay so after clearing out passwords autofill, etc. from Google Chrome settings, it now is acting as expected. Thanks for the assistance and letting me know how to get to a solution!

matthewjennings73 commented 4 years ago

A lot of time and effort from all involved here so thanks. Now working by upgrading to Django 3.0. Specail thanks to @manelclos and @shishinanliao!