We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Feature Request: remove or edit weight entry
- [ ] Remove or edit weight entry


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `wger/weight/views.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # This file is part of wger Workout Manager.
4 #
5 # wger Workout Manager is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # wger Workout Manager is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU Affero General Public License
16 
17 # Standard Library
18 import csv
19 import datetime
20 import logging
21 
22 # Django
23 from django.contrib.auth.decorators import login_required
24 from django.db.models import (
25     Max,
26     Min
27 )
28 from django.http import (
29     HttpResponse,
30     HttpResponseRedirect
31 )
32 from django.shortcuts import render
33 from django.urls import reverse
34 from django.utils.translation import (
35     ugettext as _,
36     ugettext_lazy
37 )
38 from django.views.generic import (
39     CreateView,
40     UpdateView
41 )
42 
43 # Third Party
44 from formtools.preview import FormPreview
45 from rest_framework.decorators import api_view
46 from rest_framework.response import Response
47 
48 # wger
49 from wger.utils.generic_views import WgerFormMixin
50 from wger.utils.helpers import check_access
51 from wger.weight import helpers
52 from wger.weight.forms import WeightForm
53 from wger.weight.models import WeightEntry
54 
55 
56 logger = logging.getLogger(__name__)
57 
58 
59 class WeightAddView(WgerFormMixin, CreateView):
60     """
61     Generic view to add a new weight entry
62     """
63     model = WeightEntry
64     form_class = WeightForm
65     title = ugettext_lazy('Add weight entry')
66 
67     def get_initial(self):
68         """
69         Set the initial data for the form.
70 
71         Read the comment on weight/models.py WeightEntry about why we need
72         to pass the user here.
73         """
74         return {'user': self.request.user,
75                 'date': datetime.date.today()}
76 
77     def form_valid(self, form):
78         """
79         Set the owner of the entry here
80         """
81         form.instance.user = self.request.user
82         return super(WeightAddView, self).form_valid(form)
83 
84     def get_success_url(self):
85         """
86         Return to overview with username
87         """
88         return reverse('weight:overview', kwargs={'username': self.object.user.username})
89 
90 
91 class WeightUpdateView(WgerFormMixin, UpdateView):
92     """
93     Generic view to edit an existing weight entry
94     """
95     model = WeightEntry
96     form_class = WeightForm
97 
98     def get_context_data(self, **kwargs):
99         context = super(WeightUpdateView, self).get_context_data(**kwargs)
100         context['title'] = _('Edit weight entry for the %s') % self.object.date
101 
102         return context
103 
104     def get_success_url(self):
105         """
106         Return to overview with username
107         """
108         return reverse('weight:overview', kwargs={'username': self.object.user.username})
109 
110 
111 @login_required
112 def export_csv(request):
113     """
114     Exports the saved weight data as a CSV file
115     """
116 
117     # Prepare the response headers
118     response = HttpResponse(content_type='text/csv')
119 
120     # Convert all weight data to CSV
121     writer = csv.writer(response)
122 
123     weights = WeightEntry.objects.filter(user=request.user)
124     writer.writerow([_('Weight'), _('Date')])
125 
126     for entry in weights:
127         writer.writerow([entry.weight, entry.date])
128 
129     # Send the data to the browser
130     response['Content-Disposition'] = 'attachment; filename=Weightdata.csv'
131     response['Content-Length'] = len(response.content)
132     return response
133 
134 
135 def overview(request, username=None):
136     """
137     Shows a plot with the weight data
138 
139     More info about the D3 library can be found here:
140         * https://github.com/mbostock/d3
141         * http://d3js.org/
142     """
143     is_owner, user = check_access(request.user, username)
144 
145     template_data = {}
146 
147     min_date = WeightEntry.objects.filter(user=user).\
148         aggregate(Min('date'))['date__min']
149     max_date = WeightEntry.objects.filter(user=user).\
150         aggregate(Max('date'))['date__max']
151     if min_date:
152         template_data['min_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \
153                                     {'year': min_date.year,
154                                      'month': min_date.month,
155                                      'day': min_date.day}
156     if max_date:
157         template_data['max_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \
158                                     {'year': max_date.year,
159                                      'month': max_date.month,
160                                      'day': max_date.day}
161 
162     last_weight_entries = helpers.get_last_entries(user)
163 
164     template_data['is_owner'] = is_owner
165     template_data['owner_user'] = user
166     template_data['show_shariff'] = is_owner
167     template_data['last_five_weight_entries_details'] = last_weight_entries
168     return render(request, 'overview.html', template_data)
169 
170 
171 @api_view(['GET'])
172 def get_weight_data(request, username=None):
173     """
174     Process the data to pass it to the JS libraries to generate an SVG image
175     """
176 
177     is_owner, user = check_access(request.user, username)
178 
179     date_min = request.GET.get('date_min', False)
180     date_max = request.GET.get('date_max', True)
181 
182     if date_min and date_max:
183         weights = WeightEntry.objects.filter(user=user,
184                                              date__range=(date_min, date_max))
185     else:
186         weights = WeightEntry.objects.filter(user=user)
187 
188     chart_data = []
189 
190     for i in weights:
191         chart_data.append({'date': i.date,
192                            'weight': i.weight})
193 
194     # Return the results to the client
195     return Response(chart_data)
196 
197 
198 class WeightCsvImportFormPreview(FormPreview):
199     preview_template = 'import_csv_preview.html'
200     form_template = 'import_csv_form.html'
201 
202     def get_context(self, request, form):
203         """
204         Context for template rendering.
205         """
206 
207         return {'form': form,
208                 'stage_field': self.unused_name('stage'),
209                 'state': self.state}
210 
211     def process_preview(self, request, form, context):
212         context['weight_list'], context['error_list'] = helpers.parse_weight_csv(request,
213                                                                                  form.cleaned_data)
214         return context
215 
216     def done(self, request, cleaned_data):
217         weight_list, error_list = helpers.parse_weight_csv(request, cleaned_data)
218         WeightEntry.objects.bulk_create(weight_list)
219         return HttpResponseRedirect(reverse('weight:overview',
220                                             kwargs={'username': request.user.username}))
221
```

Path: `wger/weight/urls.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # This file is part of wger Workout Manager.
4 #
5 # wger Workout Manager is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # wger Workout Manager is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU Affero General Public License
16 # along with Workout Manager.  If not, see <http://www.gnu.org/licenses/>.
17 
18 # Django
19 from django.conf.urls import url
20 from django.contrib.auth.decorators import login_required
21 
22 # wger
23 from wger.weight import views
24 from wger.weight.forms import WeightCsvImportForm
25 
26 
27 urlpatterns = [
28     url(r'^add/$',
29         login_required(views.WeightAddView.as_view()),
30         name='add'),
31 
32     url(r'^(?P<pk>\d+)/edit/$',
33         login_required(views.WeightUpdateView.as_view()),
34         name='edit'),
35 
36     url(r'^export-csv/$',
37         views.export_csv,
38         name='export-csv'),
39     url(r'^import-csv/$',
40         login_required(views.WeightCsvImportFormPreview(WeightCsvImportForm)),
41         name='import-csv'),
42 
43     url(r'^overview/(?P<username>[\w.@+-]+)$',
44         views.overview,
45         name='overview'),
46     # url(r'^overview/$',
47     #     views.overview,
48     #     name='overview'),
49     url(r'^api/get_weight_data/(?P<username>[\w.@+-]+)$',  # JS
50         views.get_weight_data,
51         name='weight-data'),
52     url(r'^api/get_weight_data/$',  # JS
53         views.get_weight_data,
54         name='weight-data'),
55 ]
56
```
--- 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()

```

diff --git a/wger/weight/urls.py b/wger/weight/urls.py
--- a/wger/weight/urls.py
+++ b/wger/weight/urls.py
@@ -33,6 +33,10 @@
         login_required(views.WeightUpdateView.as_view()),
         name='edit'),
 
+    url(r'^(?P<pk>\d+)/delete/$',
+        views.WeightDeleteView.as_view(),
+        name='delete'),
+
     url(r'^export-csv/$',
         views.export_csv,
         name='export-csv'),
diff --git a/wger/weight/views.py b/wger/weight/views.py
--- a/wger/weight/views.py
+++ b/wger/weight/views.py
@@ -21,6 +21,7 @@
 
 # Django
 from django.contrib.auth.decorators import login_required
+from django.contrib.auth.mixins import LoginRequiredMixin
 from django.db.models import (
     Max,
     Min
@@ -37,7 +38,8 @@
 )
 from django.views.generic import (
     CreateView,
-    UpdateView
+    UpdateView,
+    DeleteView
 )
 
 # Third Party
@@ -46,7 +48,10 @@
 from rest_framework.response import Response
 
 # wger
-from wger.utils.generic_views import WgerFormMixin
+from wger.utils.generic_views import (
+    WgerFormMixin,
+    WgerDeleteMixin
+)
 from wger.utils.helpers import check_access
 from wger.weight import helpers
 from wger.weight.forms import WeightForm
@@ -88,7 +93,7 @@
         return reverse('weight:overview', kwargs={'username': self.object.user.username})
 
 
-class WeightUpdateView(WgerFormMixin, UpdateView):
+class WeightUpdateView(WgerFormMixin, LoginRequiredMixin, UpdateView):
     """
     Generic view to edit an existing weight entry
     """
@@ -108,6 +113,28 @@
         return reverse('weight:overview', kwargs={'username': self.object.user.username})
 
 
+class WeightDeleteView(WgerDeleteMixin, LoginRequiredMixin, DeleteView):
+    """
+    Generic view to delete a weight entry
+    """
+
+    model = WeightEntry
+    fields = ('weight',)
+
+    messages = ugettext_lazy('Successfully deleted.')
+
+    def get_context_data(self, **kwargs):
+        context = super(WeightDeleteView, self).get_context_data(**kwargs)
+        context['title'] = _('Delete weight entry for the %s') % self.object.date
+        return context
+
+    def get_success_url(self):
+        """
+        Return to overview with username
+        """
+        return reverse('weight:overview', kwargs={'username': self.object.user.username})
+
+
 @login_required
 def export_csv(request):
     """

{"golden_diff": "diff --git a/wger/weight/urls.py b/wger/weight/urls.py\n--- a/wger/weight/urls.py\n+++ b/wger/weight/urls.py\n@@ -33,6 +33,10 @@\n         login_required(views.WeightUpdateView.as_view()),\n         name='edit'),\n \n+    url(r'^(?P<pk>\\d+)/delete/$',\n+        views.WeightDeleteView.as_view(),\n+        name='delete'),\n+\n     url(r'^export-csv/$',\n         views.export_csv,\n         name='export-csv'),\ndiff --git a/wger/weight/views.py b/wger/weight/views.py\n--- a/wger/weight/views.py\n+++ b/wger/weight/views.py\n@@ -21,6 +21,7 @@\n \n # Django\n from django.contrib.auth.decorators import login_required\n+from django.contrib.auth.mixins import LoginRequiredMixin\n from django.db.models import (\n     Max,\n     Min\n@@ -37,7 +38,8 @@\n )\n from django.views.generic import (\n     CreateView,\n-    UpdateView\n+    UpdateView,\n+    DeleteView\n )\n \n # Third Party\n@@ -46,7 +48,10 @@\n from rest_framework.response import Response\n \n # wger\n-from wger.utils.generic_views import WgerFormMixin\n+from wger.utils.generic_views import (\n+    WgerFormMixin,\n+    WgerDeleteMixin\n+)\n from wger.utils.helpers import check_access\n from wger.weight import helpers\n from wger.weight.forms import WeightForm\n@@ -88,7 +93,7 @@\n         return reverse('weight:overview', kwargs={'username': self.object.user.username})\n \n \n-class WeightUpdateView(WgerFormMixin, UpdateView):\n+class WeightUpdateView(WgerFormMixin, LoginRequiredMixin, UpdateView):\n     \"\"\"\n     Generic view to edit an existing weight entry\n     \"\"\"\n@@ -108,6 +113,28 @@\n         return reverse('weight:overview', kwargs={'username': self.object.user.username})\n \n \n+class WeightDeleteView(WgerDeleteMixin, LoginRequiredMixin, DeleteView):\n+    \"\"\"\n+    Generic view to delete a weight entry\n+    \"\"\"\n+\n+    model = WeightEntry\n+    fields = ('weight',)\n+\n+    messages = ugettext_lazy('Successfully deleted.')\n+\n+    def get_context_data(self, **kwargs):\n+        context = super(WeightDeleteView, self).get_context_data(**kwargs)\n+        context['title'] = _('Delete weight entry for the %s') % self.object.date\n+        return context\n+\n+    def get_success_url(self):\n+        \"\"\"\n+        Return to overview with username\n+        \"\"\"\n+        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n+\n+\n @login_required\n def export_csv(request):\n     \"\"\"\n", "issue": "Feature Request: remove or edit weight entry\n- [ ] Remove or edit weight entry\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# This file is part of wger Workout Manager.\n#\n# wger Workout Manager is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# wger Workout Manager is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n\n# Standard Library\nimport csv\nimport datetime\nimport logging\n\n# Django\nfrom django.contrib.auth.decorators import login_required\nfrom django.db.models import (\n    Max,\n    Min\n)\nfrom django.http import (\n    HttpResponse,\n    HttpResponseRedirect\n)\nfrom django.shortcuts import render\nfrom django.urls import reverse\nfrom django.utils.translation import (\n    ugettext as _,\n    ugettext_lazy\n)\nfrom django.views.generic import (\n    CreateView,\n    UpdateView\n)\n\n# Third Party\nfrom formtools.preview import FormPreview\nfrom rest_framework.decorators import api_view\nfrom rest_framework.response import Response\n\n# wger\nfrom wger.utils.generic_views import WgerFormMixin\nfrom wger.utils.helpers import check_access\nfrom wger.weight import helpers\nfrom wger.weight.forms import WeightForm\nfrom wger.weight.models import WeightEntry\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass WeightAddView(WgerFormMixin, CreateView):\n    \"\"\"\n    Generic view to add a new weight entry\n    \"\"\"\n    model = WeightEntry\n    form_class = WeightForm\n    title = ugettext_lazy('Add weight entry')\n\n    def get_initial(self):\n        \"\"\"\n        Set the initial data for the form.\n\n        Read the comment on weight/models.py WeightEntry about why we need\n        to pass the user here.\n        \"\"\"\n        return {'user': self.request.user,\n                'date': datetime.date.today()}\n\n    def form_valid(self, form):\n        \"\"\"\n        Set the owner of the entry here\n        \"\"\"\n        form.instance.user = self.request.user\n        return super(WeightAddView, self).form_valid(form)\n\n    def get_success_url(self):\n        \"\"\"\n        Return to overview with username\n        \"\"\"\n        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n\n\nclass WeightUpdateView(WgerFormMixin, UpdateView):\n    \"\"\"\n    Generic view to edit an existing weight entry\n    \"\"\"\n    model = WeightEntry\n    form_class = WeightForm\n\n    def get_context_data(self, **kwargs):\n        context = super(WeightUpdateView, self).get_context_data(**kwargs)\n        context['title'] = _('Edit weight entry for the %s') % self.object.date\n\n        return context\n\n    def get_success_url(self):\n        \"\"\"\n        Return to overview with username\n        \"\"\"\n        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n\n\n@login_required\ndef export_csv(request):\n    \"\"\"\n    Exports the saved weight data as a CSV file\n    \"\"\"\n\n    # Prepare the response headers\n    response = HttpResponse(content_type='text/csv')\n\n    # Convert all weight data to CSV\n    writer = csv.writer(response)\n\n    weights = WeightEntry.objects.filter(user=request.user)\n    writer.writerow([_('Weight'), _('Date')])\n\n    for entry in weights:\n        writer.writerow([entry.weight, entry.date])\n\n    # Send the data to the browser\n    response['Content-Disposition'] = 'attachment; filename=Weightdata.csv'\n    response['Content-Length'] = len(response.content)\n    return response\n\n\ndef overview(request, username=None):\n    \"\"\"\n    Shows a plot with the weight data\n\n    More info about the D3 library can be found here:\n        * https://github.com/mbostock/d3\n        * http://d3js.org/\n    \"\"\"\n    is_owner, user = check_access(request.user, username)\n\n    template_data = {}\n\n    min_date = WeightEntry.objects.filter(user=user).\\\n        aggregate(Min('date'))['date__min']\n    max_date = WeightEntry.objects.filter(user=user).\\\n        aggregate(Max('date'))['date__max']\n    if min_date:\n        template_data['min_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \\\n                                    {'year': min_date.year,\n                                     'month': min_date.month,\n                                     'day': min_date.day}\n    if max_date:\n        template_data['max_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \\\n                                    {'year': max_date.year,\n                                     'month': max_date.month,\n                                     'day': max_date.day}\n\n    last_weight_entries = helpers.get_last_entries(user)\n\n    template_data['is_owner'] = is_owner\n    template_data['owner_user'] = user\n    template_data['show_shariff'] = is_owner\n    template_data['last_five_weight_entries_details'] = last_weight_entries\n    return render(request, 'overview.html', template_data)\n\n\n@api_view(['GET'])\ndef get_weight_data(request, username=None):\n    \"\"\"\n    Process the data to pass it to the JS libraries to generate an SVG image\n    \"\"\"\n\n    is_owner, user = check_access(request.user, username)\n\n    date_min = request.GET.get('date_min', False)\n    date_max = request.GET.get('date_max', True)\n\n    if date_min and date_max:\n        weights = WeightEntry.objects.filter(user=user,\n                                             date__range=(date_min, date_max))\n    else:\n        weights = WeightEntry.objects.filter(user=user)\n\n    chart_data = []\n\n    for i in weights:\n        chart_data.append({'date': i.date,\n                           'weight': i.weight})\n\n    # Return the results to the client\n    return Response(chart_data)\n\n\nclass WeightCsvImportFormPreview(FormPreview):\n    preview_template = 'import_csv_preview.html'\n    form_template = 'import_csv_form.html'\n\n    def get_context(self, request, form):\n        \"\"\"\n        Context for template rendering.\n        \"\"\"\n\n        return {'form': form,\n                'stage_field': self.unused_name('stage'),\n                'state': self.state}\n\n    def process_preview(self, request, form, context):\n        context['weight_list'], context['error_list'] = helpers.parse_weight_csv(request,\n                                                                                 form.cleaned_data)\n        return context\n\n    def done(self, request, cleaned_data):\n        weight_list, error_list = helpers.parse_weight_csv(request, cleaned_data)\n        WeightEntry.objects.bulk_create(weight_list)\n        return HttpResponseRedirect(reverse('weight:overview',\n                                            kwargs={'username': request.user.username}))\n", "path": "wger/weight/views.py"}, {"content": "# -*- coding: utf-8 -*-\n\n# This file is part of wger Workout Manager.\n#\n# wger Workout Manager is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# wger Workout Manager is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with Workout Manager.  If not, see <http://www.gnu.org/licenses/>.\n\n# Django\nfrom django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\n\n# wger\nfrom wger.weight import views\nfrom wger.weight.forms import WeightCsvImportForm\n\n\nurlpatterns = [\n    url(r'^add/$',\n        login_required(views.WeightAddView.as_view()),\n        name='add'),\n\n    url(r'^(?P<pk>\\d+)/edit/$',\n        login_required(views.WeightUpdateView.as_view()),\n        name='edit'),\n\n    url(r'^export-csv/$',\n        views.export_csv,\n        name='export-csv'),\n    url(r'^import-csv/$',\n        login_required(views.WeightCsvImportFormPreview(WeightCsvImportForm)),\n        name='import-csv'),\n\n    url(r'^overview/(?P<username>[\\w.@+-]+)$',\n        views.overview,\n        name='overview'),\n    # url(r'^overview/$',\n    #     views.overview,\n    #     name='overview'),\n    url(r'^api/get_weight_data/(?P<username>[\\w.@+-]+)$',  # JS\n        views.get_weight_data,\n        name='weight-data'),\n    url(r'^api/get_weight_data/$',  # JS\n        views.get_weight_data,\n        name='weight-data'),\n]\n", "path": "wger/weight/urls.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# This file is part of wger Workout Manager.\n#\n# wger Workout Manager is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# wger Workout Manager is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n\n# Standard Library\nimport csv\nimport datetime\nimport logging\n\n# Django\nfrom django.contrib.auth.decorators import login_required\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.db.models import (\n    Max,\n    Min\n)\nfrom django.http import (\n    HttpResponse,\n    HttpResponseRedirect\n)\nfrom django.shortcuts import render\nfrom django.urls import reverse\nfrom django.utils.translation import (\n    ugettext as _,\n    ugettext_lazy\n)\nfrom django.views.generic import (\n    CreateView,\n    UpdateView,\n    DeleteView\n)\n\n# Third Party\nfrom formtools.preview import FormPreview\nfrom rest_framework.decorators import api_view\nfrom rest_framework.response import Response\n\n# wger\nfrom wger.utils.generic_views import (\n    WgerFormMixin,\n    WgerDeleteMixin\n)\nfrom wger.utils.helpers import check_access\nfrom wger.weight import helpers\nfrom wger.weight.forms import WeightForm\nfrom wger.weight.models import WeightEntry\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass WeightAddView(WgerFormMixin, CreateView):\n    \"\"\"\n    Generic view to add a new weight entry\n    \"\"\"\n    model = WeightEntry\n    form_class = WeightForm\n    title = ugettext_lazy('Add weight entry')\n\n    def get_initial(self):\n        \"\"\"\n        Set the initial data for the form.\n\n        Read the comment on weight/models.py WeightEntry about why we need\n        to pass the user here.\n        \"\"\"\n        return {'user': self.request.user,\n                'date': datetime.date.today()}\n\n    def form_valid(self, form):\n        \"\"\"\n        Set the owner of the entry here\n        \"\"\"\n        form.instance.user = self.request.user\n        return super(WeightAddView, self).form_valid(form)\n\n    def get_success_url(self):\n        \"\"\"\n        Return to overview with username\n        \"\"\"\n        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n\n\nclass WeightUpdateView(WgerFormMixin, LoginRequiredMixin, UpdateView):\n    \"\"\"\n    Generic view to edit an existing weight entry\n    \"\"\"\n    model = WeightEntry\n    form_class = WeightForm\n\n    def get_context_data(self, **kwargs):\n        context = super(WeightUpdateView, self).get_context_data(**kwargs)\n        context['title'] = _('Edit weight entry for the %s') % self.object.date\n\n        return context\n\n    def get_success_url(self):\n        \"\"\"\n        Return to overview with username\n        \"\"\"\n        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n\n\nclass WeightDeleteView(WgerDeleteMixin, LoginRequiredMixin, DeleteView):\n    \"\"\"\n    Generic view to delete a weight entry\n    \"\"\"\n\n    model = WeightEntry\n    fields = ('weight',)\n\n    messages = ugettext_lazy('Successfully deleted.')\n\n    def get_context_data(self, **kwargs):\n        context = super(WeightDeleteView, self).get_context_data(**kwargs)\n        context['title'] = _('Delete weight entry for the %s') % self.object.date\n        return context\n\n    def get_success_url(self):\n        \"\"\"\n        Return to overview with username\n        \"\"\"\n        return reverse('weight:overview', kwargs={'username': self.object.user.username})\n\n\n@login_required\ndef export_csv(request):\n    \"\"\"\n    Exports the saved weight data as a CSV file\n    \"\"\"\n\n    # Prepare the response headers\n    response = HttpResponse(content_type='text/csv')\n\n    # Convert all weight data to CSV\n    writer = csv.writer(response)\n\n    weights = WeightEntry.objects.filter(user=request.user)\n    writer.writerow([_('Weight'), _('Date')])\n\n    for entry in weights:\n        writer.writerow([entry.weight, entry.date])\n\n    # Send the data to the browser\n    response['Content-Disposition'] = 'attachment; filename=Weightdata.csv'\n    response['Content-Length'] = len(response.content)\n    return response\n\n\ndef overview(request, username=None):\n    \"\"\"\n    Shows a plot with the weight data\n\n    More info about the D3 library can be found here:\n        * https://github.com/mbostock/d3\n        * http://d3js.org/\n    \"\"\"\n    is_owner, user = check_access(request.user, username)\n\n    template_data = {}\n\n    min_date = WeightEntry.objects.filter(user=user).\\\n        aggregate(Min('date'))['date__min']\n    max_date = WeightEntry.objects.filter(user=user).\\\n        aggregate(Max('date'))['date__max']\n    if min_date:\n        template_data['min_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \\\n                                    {'year': min_date.year,\n                                     'month': min_date.month,\n                                     'day': min_date.day}\n    if max_date:\n        template_data['max_date'] = 'new Date(%(year)s, %(month)s, %(day)s)' % \\\n                                    {'year': max_date.year,\n                                     'month': max_date.month,\n                                     'day': max_date.day}\n\n    last_weight_entries = helpers.get_last_entries(user)\n\n    template_data['is_owner'] = is_owner\n    template_data['owner_user'] = user\n    template_data['show_shariff'] = is_owner\n    template_data['last_five_weight_entries_details'] = last_weight_entries\n    return render(request, 'overview.html', template_data)\n\n\n@api_view(['GET'])\ndef get_weight_data(request, username=None):\n    \"\"\"\n    Process the data to pass it to the JS libraries to generate an SVG image\n    \"\"\"\n\n    is_owner, user = check_access(request.user, username)\n\n    date_min = request.GET.get('date_min', False)\n    date_max = request.GET.get('date_max', True)\n\n    if date_min and date_max:\n        weights = WeightEntry.objects.filter(user=user,\n                                             date__range=(date_min, date_max))\n    else:\n        weights = WeightEntry.objects.filter(user=user)\n\n    chart_data = []\n\n    for i in weights:\n        chart_data.append({'date': i.date,\n                           'weight': i.weight})\n\n    # Return the results to the client\n    return Response(chart_data)\n\n\nclass WeightCsvImportFormPreview(FormPreview):\n    preview_template = 'import_csv_preview.html'\n    form_template = 'import_csv_form.html'\n\n    def get_context(self, request, form):\n        \"\"\"\n        Context for template rendering.\n        \"\"\"\n\n        return {'form': form,\n                'stage_field': self.unused_name('stage'),\n                'state': self.state}\n\n    def process_preview(self, request, form, context):\n        context['weight_list'], context['error_list'] = helpers.parse_weight_csv(request,\n                                                                                 form.cleaned_data)\n        return context\n\n    def done(self, request, cleaned_data):\n        weight_list, error_list = helpers.parse_weight_csv(request, cleaned_data)\n        WeightEntry.objects.bulk_create(weight_list)\n        return HttpResponseRedirect(reverse('weight:overview',\n                                            kwargs={'username': request.user.username}))\n", "path": "wger/weight/views.py"}, {"content": "# -*- coding: utf-8 -*-\n\n# This file is part of wger Workout Manager.\n#\n# wger Workout Manager is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# wger Workout Manager is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with Workout Manager.  If not, see <http://www.gnu.org/licenses/>.\n\n# Django\nfrom django.conf.urls import url\nfrom django.contrib.auth.decorators import login_required\n\n# wger\nfrom wger.weight import views\nfrom wger.weight.forms import WeightCsvImportForm\n\n\nurlpatterns = [\n    url(r'^add/$',\n        login_required(views.WeightAddView.as_view()),\n        name='add'),\n\n    url(r'^(?P<pk>\\d+)/edit/$',\n        login_required(views.WeightUpdateView.as_view()),\n        name='edit'),\n\n    url(r'^(?P<pk>\\d+)/delete/$',\n        views.WeightDeleteView.as_view(),\n        name='delete'),\n\n    url(r'^export-csv/$',\n        views.export_csv,\n        name='export-csv'),\n    url(r'^import-csv/$',\n        login_required(views.WeightCsvImportFormPreview(WeightCsvImportForm)),\n        name='import-csv'),\n\n    url(r'^overview/(?P<username>[\\w.@+-]+)$',\n        views.overview,\n        name='overview'),\n    # url(r'^overview/$',\n    #     views.overview,\n    #     name='overview'),\n    url(r'^api/get_weight_data/(?P<username>[\\w.@+-]+)$',  # JS\n        views.get_weight_data,\n        name='weight-data'),\n    url(r'^api/get_weight_data/$',  # JS\n        views.get_weight_data,\n        name='weight-data'),\n]\n", "path": "wger/weight/urls.py"}]}