prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Deleting and re-adding widgets to a dashboard breaks it
  There's a specific set of steps that has messed up some of our users' dashboards:
  1. Create a new dashboard
  2. Add multiple widgets to it.
  3. Remove all those widgets from the dashboard
  4. Re-add some widgets
  5. Click the "Edit Dashboard (Name/Layout)" button
  6. Click Save without changing anything.
  7. Refresh the page
  
  This makes none of the widgets appear and causes the "Layout" array in the admin panel to contain one or more "null" values (depending on how many widgets you added/deleted):
  ![image](https://cloud.githubusercontent.com/assets/844493/11826038/76c749fa-a348-11e5-9f46-bbae43c4b6f6.png)
  
  The only way to recover from this state is to manually delete the "null" values through the admin interface.
  
  This is on re:dash version 0.8.2
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `redash/handlers/widgets.py`
  Content:
  ```
  1 import json
  2 
  3 from flask import request
  4 
  5 from redash import models
  6 from redash.wsgi import api
  7 from redash.permissions import require_permission
  8 from redash.handlers.base import BaseResource
  9 
  10 
  11 class WidgetListAPI(BaseResource):
  12     @require_permission('edit_dashboard')
  13     def post(self):
  14         widget_properties = request.get_json(force=True)
  15         widget_properties['options'] = json.dumps(widget_properties['options'])
  16         widget_properties.pop('id', None)
  17         widget_properties['dashboard'] = widget_properties.pop('dashboard_id')
  18         widget_properties['visualization'] = widget_properties.pop('visualization_id')
  19         widget = models.Widget(**widget_properties)
  20         widget.save()
  21 
  22         layout = json.loads(widget.dashboard.layout)
  23         new_row = True
  24 
  25         if len(layout) == 0 or widget.width == 2:
  26             layout.append([widget.id])
  27         elif len(layout[-1]) == 1:
  28             neighbour_widget = models.Widget.get(models.Widget.id == layout[-1][0])
  29             if neighbour_widget.width == 1:
  30                 layout[-1].append(widget.id)
  31                 new_row = False
  32             else:
  33                 layout.append([widget.id])
  34         else:
  35             layout.append([widget.id])
  36 
  37         widget.dashboard.layout = json.dumps(layout)
  38         widget.dashboard.save()
  39 
  40         return {'widget': widget.to_dict(), 'layout': layout, 'new_row': new_row}
  41 
  42 
  43 class WidgetAPI(BaseResource):
  44     @require_permission('edit_dashboard')
  45     def delete(self, widget_id):
  46         widget = models.Widget.get(models.Widget.id == widget_id)
  47         widget.delete_instance()
  48 
  49 api.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')
  50 api.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')
  51
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/redash/handlers/widgets.py b/redash/handlers/widgets.py
  --- a/redash/handlers/widgets.py
  +++ b/redash/handlers/widgets.py
  @@ -46,5 +46,7 @@
           widget = models.Widget.get(models.Widget.id == widget_id)
           widget.delete_instance()
   
  +        return {'layout': widget.dashboard.layout }
  +
   api.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')
   api.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')
  
verification_info: {"golden_diff": "diff --git a/redash/handlers/widgets.py b/redash/handlers/widgets.py\n--- a/redash/handlers/widgets.py\n+++ b/redash/handlers/widgets.py\n@@ -46,5 +46,7 @@\n         widget = models.Widget.get(models.Widget.id == widget_id)\n         widget.delete_instance()\n \n+        return {'layout': widget.dashboard.layout }\n+\n api.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')\n api.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')\n", "issue": "Deleting and re-adding widgets to a dashboard breaks it\nThere's a specific set of steps that has messed up some of our users' dashboards:\n1. Create a new dashboard\n2. Add multiple widgets to it.\n3. Remove all those widgets from the dashboard\n4. Re-add some widgets\n5. Click the \"Edit Dashboard (Name/Layout)\" button\n6. Click Save without changing anything.\n7. Refresh the page\n\nThis makes none of the widgets appear and causes the \"Layout\" array in the admin panel to contain one or more \"null\" values (depending on how many widgets you added/deleted):\n![image](https://cloud.githubusercontent.com/assets/844493/11826038/76c749fa-a348-11e5-9f46-bbae43c4b6f6.png)\n\nThe only way to recover from this state is to manually delete the \"null\" values through the admin interface.\n\nThis is on re:dash version 0.8.2\n\n", "before_files": [{"content": "import json\n\nfrom flask import request\n\nfrom redash import models\nfrom redash.wsgi import api\nfrom redash.permissions import require_permission\nfrom redash.handlers.base import BaseResource\n\n\nclass WidgetListAPI(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self):\n        widget_properties = request.get_json(force=True)\n        widget_properties['options'] = json.dumps(widget_properties['options'])\n        widget_properties.pop('id', None)\n        widget_properties['dashboard'] = widget_properties.pop('dashboard_id')\n        widget_properties['visualization'] = widget_properties.pop('visualization_id')\n        widget = models.Widget(**widget_properties)\n        widget.save()\n\n        layout = json.loads(widget.dashboard.layout)\n        new_row = True\n\n        if len(layout) == 0 or widget.width == 2:\n            layout.append([widget.id])\n        elif len(layout[-1]) == 1:\n            neighbour_widget = models.Widget.get(models.Widget.id == layout[-1][0])\n            if neighbour_widget.width == 1:\n                layout[-1].append(widget.id)\n                new_row = False\n            else:\n                layout.append([widget.id])\n        else:\n            layout.append([widget.id])\n\n        widget.dashboard.layout = json.dumps(layout)\n        widget.dashboard.save()\n\n        return {'widget': widget.to_dict(), 'layout': layout, 'new_row': new_row}\n\n\nclass WidgetAPI(BaseResource):\n    @require_permission('edit_dashboard')\n    def delete(self, widget_id):\n        widget = models.Widget.get(models.Widget.id == widget_id)\n        widget.delete_instance()\n\napi.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')\napi.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')\n", "path": "redash/handlers/widgets.py"}], "after_files": [{"content": "import json\n\nfrom flask import request\n\nfrom redash import models\nfrom redash.wsgi import api\nfrom redash.permissions import require_permission\nfrom redash.handlers.base import BaseResource\n\n\nclass WidgetListAPI(BaseResource):\n    @require_permission('edit_dashboard')\n    def post(self):\n        widget_properties = request.get_json(force=True)\n        widget_properties['options'] = json.dumps(widget_properties['options'])\n        widget_properties.pop('id', None)\n        widget_properties['dashboard'] = widget_properties.pop('dashboard_id')\n        widget_properties['visualization'] = widget_properties.pop('visualization_id')\n        widget = models.Widget(**widget_properties)\n        widget.save()\n\n        layout = json.loads(widget.dashboard.layout)\n        new_row = True\n\n        if len(layout) == 0 or widget.width == 2:\n            layout.append([widget.id])\n        elif len(layout[-1]) == 1:\n            neighbour_widget = models.Widget.get(models.Widget.id == layout[-1][0])\n            if neighbour_widget.width == 1:\n                layout[-1].append(widget.id)\n                new_row = False\n            else:\n                layout.append([widget.id])\n        else:\n            layout.append([widget.id])\n\n        widget.dashboard.layout = json.dumps(layout)\n        widget.dashboard.save()\n\n        return {'widget': widget.to_dict(), 'layout': layout, 'new_row': new_row}\n\n\nclass WidgetAPI(BaseResource):\n    @require_permission('edit_dashboard')\n    def delete(self, widget_id):\n        widget = models.Widget.get(models.Widget.id == widget_id)\n        widget.delete_instance()\n\n        return {'layout': widget.dashboard.layout }\n\napi.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')\napi.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')\n", "path": "redash/handlers/widgets.py"}]}