diff --git a/Api/views.py b/Api/views.py index b343c7cd..b8ea70bc 100644 --- a/Api/views.py +++ b/Api/views.py @@ -59,6 +59,11 @@ def CategoryList(request): serializer = CategorySerializer(cats, many=True) return Response(serializer.data) +# One function with CRUD , including type "PUT","GET","POST","DELETE" +# class CategoryList(viewsets.ModelViewSet): +# serializer_class = CategorySerializer +# queryset = Category.objects.all().order_by('-created_at') + @api_view(['POST']) @permission_classes((permissions.IsAuthenticated,)) diff --git a/book/custom_filter.py b/book/custom_filter.py index 1ba43b94..63007dc7 100644 --- a/book/custom_filter.py +++ b/book/custom_filter.py @@ -8,8 +8,5 @@ def get_item(dictionary, key): @register.filter('has_group') def has_group(user, group_name): - """ - Verifica se este usuário pertence a um grupo - """ groups = user.groups.all().values_list('name', flat=True) return True if group_name in groups else False \ No newline at end of file diff --git a/book/forms.py b/book/forms.py index ca574c7b..6d4c610f 100644 --- a/book/forms.py +++ b/book/forms.py @@ -3,6 +3,7 @@ from django.contrib.admin.widgets import AutocompleteSelect from django.contrib import admin from django.urls import reverse +from flatpickr import DatePickerInput, TimePickerInput, DateTimePickerInput class BookCreateEditForm(forms.ModelForm): @@ -59,8 +60,34 @@ class BorrowRecordCreateForm(forms.ModelForm): class Meta: model = BorrowRecord fields=['borrower','book','quantity','start_day','end_day'] + # widgets = { + # 'start_day': DatePickerInput().start_of('event datetime'), + # 'end_day': DatePickerInput().end_of('event datetime'), + # } + widgets = { + 'start_day': DatePickerInput(options = { "dateFormat": "Y-m-d", }), + 'end_day': DatePickerInput(options = { "dateFormat": "Y-m-d", }), + } + # widgets = {'start_day': forms.DateTimeInput(attrs={'class': 'datepicker'}), + # 'end_day': forms.DateTimeInput(attrs={'class': 'datepicker'})} + # widgets = { # 'start_day': DateTimePickerInput(format='%Y-%m-%d'), # 'end_day': DateTimePickerInput(format='%Y-%m-%d'), - # } \ No newline at end of file + # } + + +# from django.forms.widgets import SelectDateWidget + +# class BorrowRecordCreateForm(forms.ModelForm): + +# def __init__(self, *args, **kwargs): +# super(BorrowRecordCreateForm, self).__init__(*args, **kwargs) +# #Change date field's widget here +# self.fields['start_day'].widget = SelectDateWidget() +# self.fields['end_day'].widget = SelectDateWidget() + +# class Meta: +# model = BorrowRecord +# fields=['borrower','book','quantity','start_day','end_day'] diff --git a/book/urls.py b/book/urls.py index 90107aaf..51a7aaec 100644 --- a/book/urls.py +++ b/book/urls.py @@ -54,6 +54,8 @@ # BorrowRecords path('record-create/',BorrowRecordCreateView.as_view(),name="record_create"), + # path('record-create/',record_create,name="record_create"), + path('record-create-autocomplete-member-name/',auto_member,name="auto_member_name"), path('record-create-autocomplete-book-name/',auto_book,name="auto_book_name"), path('record-list/',BorrowRecordListView.as_view(),name="record_list"), diff --git a/book/views.py b/book/views.py index 6aa22a4f..0a67b0cc 100644 --- a/book/views.py +++ b/book/views.py @@ -79,7 +79,6 @@ def get(self,request, *args, **kwargs): user_activities= UserActivity.objects.order_by("-created_at")[:5] user_avatar = { e.created_by:Profile.objects.get(user__username=e.created_by).profile_pic.url for e in user_activities} - short_inventory =Book.objects.order_by('quantity')[:5] current_week = date.today().isocalendar()[1] @@ -167,7 +166,6 @@ def get(self,request, *args, **kwargs): return render(request, self.template_name, self.context) # Book - class BookListView(LoginRequiredMixin,ListView): login_url = 'login' model=Book @@ -696,39 +694,122 @@ class BorrowRecordCreateView(LoginRequiredMixin,CreateView): form_class=BorrowRecordCreateForm login_url = 'login' + + def get_form(self): form = super().get_form() return form def form_valid(self, form): selected_member= get_object_or_404(Member,name = form.cleaned_data['borrower'] ) + selected_book = Book.objects.get(title=form.cleaned_data['book']) + + # if form.is_valid(): + # form.save(commit=True) + # return HttpResponse("Successfully added the date to database"); + # else: + # # The supplied form contained errors - just print them to the terminal. + # print(form.errors) + form.instance.borrower_card = selected_member.card_number form.instance.borrower_email = selected_member.email form.instance.borrower_phone_number = selected_member.phone_number form.instance.created_by = self.request.user.username + form.instance.start_day = form.cleaned_data['start_day'] + form.instance.end_day = form.cleaned_data['end_day'] form.save() - return super(BorrowRecordCreateView,self).form_valid(form) - - def post(self,request, *args, **kwargs): - super(BorrowRecordCreateView,self).post(request) - selected_member= Member.objects.get(name=request.POST['borrower']) - selected_book = Book.objects.get(title=request.POST['book']) - + # Change field on Model Book selected_book.status=0 selected_book.total_borrow_times+=1 - selected_book.quantity-=int(request.POST['quantity']) + selected_book.quantity-=int(form.cleaned_data['quantity']) selected_book.save() # Create Log borrower_name = selected_member.name book_name = selected_book.title - messages.success(request, f" '{borrower_name}' borrowed <<{book_name}>>") + + messages.success(self.request, f" '{borrower_name}' borrowed <<{book_name}>>") UserActivity.objects.create(created_by=self.request.user.username, target_model=self.model.__name__, detail =f" '{borrower_name}' borrowed <<{book_name}>>") - return redirect('record_list') + + + return super(BorrowRecordCreateView,self).form_valid(form) + + + # def post(self,request, *args, **kwargs): + # super(BorrowRecordCreateView,self).post(request) + + # start_day = request.POST['start_day'] + + # selected_member= Member.objects.get(name=request.POST['borrower']) + # selected_book = Book.objects.get(title=request.POST['book']) + + # # Change field on Model Book + # selected_book.status=0 + # selected_book.total_borrow_times+=1 + # selected_book.quantity-=int(request.POST['quantity']) + # selected_book.save() + + # # Create Log + # borrower_name = selected_member.name + # book_name = selected_book.title + # messages.success(request, f" '{borrower_name}' borrowed <<{book_name}>>") + # UserActivity.objects.create(created_by=self.request.user.username, + # target_model=self.model.__name__, + # detail =f" '{borrower_name}' borrowed <<{book_name}>>") + # return redirect('record_list') + +# @login_required(login_url='login') +# def record_create(request): +# # 判断用户是否提交数据 +# if request.method == "POST": +# record_post_form = BorrowRecordCreateForm(request.POST) +# # 判断提交的数据是否满足模型的要求 +# if record_post_form.is_valid(): +# new_record = record_post_form.save(commit=False) + + +# selected_member= get_object_or_404(Member,name = record_post_form.cleaned_data['borrower'] ) +# selected_book = Book.objects.get(title=record_post_form.cleaned_data['book']) +# new_record.borrower_card = selected_member.card_number +# new_record.borrower_email = selected_member.email +# new_record.borrower_phone_number = selected_member.phone_number +# new_record.created_by = request.user.username +# # print(datetime.strptime(record_post_form.cleaned_data['start_day'], "%Y/%m/%d %H:%M:%S")) +# # print(datetime.strptime(record_post_form.cleaned_data['end_day'], "%Y/%m/%d %H:%M:%S")) + +# new_record.start_day = datetime.strptime(record_post_form.cleaned_data['start_day'],"%Y-%m-%d %H:%M:%S") +# new_record.end_day = datetime.strptime(record_post_form.cleaned_data['end_day'],"%Y-%m-%d %H:%M:%S") +# new_record.save() + +# # Change field on Model Book +# selected_book.status=0 +# selected_book.total_borrow_times+=1 +# selected_book.quantity-=int(request.POST['quantity']) +# selected_book.save() + +# # Create Log +# borrower_name = selected_member.name +# book_name = selected_book.title +# messages.success(request, f" '{borrower_name}' borrowed <<{book_name}>>") +# UserActivity.objects.create(created_by=request.user.username, +# target_model='BorrowRecord', +# detail =f" '{borrower_name}' borrowed <<{book_name}>>") +# return redirect("record_list") +# else: +# print(record_post_form.errors) +# return HttpResponse("Error with form") +# # 如果用户请求获取数据 +# else: +# record_post_form = BorrowRecordCreateForm() +# context = { 'form': record_post_form, } + +# return render(request, 'borrow_records/create.html', context) + + @login_required(login_url='login') def auto_member(request): diff --git a/core/settings.py b/core/settings.py index f9cbc4f4..a608f114 100644 --- a/core/settings.py +++ b/core/settings.py @@ -42,9 +42,7 @@ 'ckeditor', 'comment', 'notifications', - # 'elasticsearch-dsl', - # 'django_elasticsearch_dsl', - # 'django-elasticsearch-dsl-drf', + 'flatpickr', ] CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind" @@ -54,9 +52,9 @@ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.cache.UpdateCacheMiddleware', # Redis + # 'django.middleware.cache.UpdateCacheMiddleware', # Redis 'django.middleware.common.CommonMiddleware', - 'django.middleware.cache.FetchFromCacheMiddleware', # Redis + # 'django.middleware.cache.FetchFromCacheMiddleware', # Redis 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', @@ -129,7 +127,6 @@ WSGI_APPLICATION = 'core.wsgi.application' - DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', @@ -234,15 +231,15 @@ DATA_ROOT = os.path.join(BASE_DIR, 'data') -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": "redis://127.0.0.1:6379/1", - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - # "PASSWORD": "mysecret" - "SOCKET_CONNECT_TIMEOUT": 5, - "SOCKET_TIMEOUT": 5, - } - } -} +# CACHES = { +# "default": { +# "BACKEND": "django_redis.cache.RedisCache", +# "LOCATION": "redis://127.0.0.1:6379/1", +# "OPTIONS": { +# "CLIENT_CLASS": "django_redis.client.DefaultClient", +# # "PASSWORD": "mysecret" +# "SOCKET_CONNECT_TIMEOUT": 5, +# "SOCKET_TIMEOUT": 5, +# } +# } +# } diff --git a/datacenter/Category_20210908.csv b/datacenter/Category_20210908.csv new file mode 100644 index 00000000..cb3554f1 --- /dev/null +++ b/datacenter/Category_20210908.csv @@ -0,0 +1,13 @@ +id,name,created_at +2,Economics,2021-07-31 18:19:30.473140+00:00 +3,Finance,2021-07-31 18:19:43.229982+00:00 +4,Historical,2021-07-31 18:19:49.221871+00:00 +5,Fantasy,2021-07-31 18:19:56.916918+00:00 +6,Cooking,2021-07-31 18:20:02.315268+00:00 +7,Computers & Tech,2021-07-31 18:20:10.279309+00:00 +8,Fiction,2021-07-31 18:20:17.988670+00:00 +9,Watch,2021-07-31 18:20:31.205351+00:00 +10,Detective and Mystery,2021-07-31 18:20:36.975123+00:00 +11,Literary Fiction,2021-07-31 18:20:41.851775+00:00 +12,Comic,2021-07-31 18:20:54.997368+00:00 +20,Fashion,2021-08-09 17:29:13.408340+00:00 diff --git a/datacenter/Member_20210907.csv b/datacenter/Member_20210907.csv new file mode 100644 index 00000000..2b7e4616 --- /dev/null +++ b/datacenter/Member_20210907.csv @@ -0,0 +1,20 @@ +id,name,age,gender,city,email,phone_number,created_at,created_by,updated_by,updated_at,card_id,card_number,expired_at +1,test_m1,20,m,London,test_m1@gmail.com,15800000000,2021-07-31 18:24:22.399715+00:00,yaozeliang,,2021-07-31 18:24:22.400716+00:00,41dced50-32bc-43c9-9904-e611acf969cb,41dced50,2022-07-31 18:24:22.400716+00:00 +2,test_m3,18,m,Paris,test_3@gmail.com,13666666666,2021-07-31 18:24:51.578547+00:00,yaozeliang,admin_1,2021-07-31 18:27:11.126713+00:00,4571a875-cf32-42d0-ba4e-5f54f395e09d,4571a875,2022-07-31 18:27:11.126713+00:00 +3,test_m2,20,m,Paris,test_m2@gmail.com,13000000000,2021-07-31 18:27:37.716707+00:00,admin_1,,2021-07-31 18:27:37.717708+00:00,d488c8c1-fc08-4502-ad54-cdc2c72a818f,d488c8c1,2022-07-31 18:27:37.717708+00:00 +4,test_m4,20,m,Beijing,test_m4@gmail.com,13600000000,2021-07-31 20:29:29.402416+00:00,yaozeliang,,2021-07-31 20:29:29.408377+00:00,709d3c7d-f2ff-48b6-b80e-2e49c59ddc7f,709d3c7d,2022-07-31 20:29:29.407381+00:00 +5,test_m7,20,m,Beijing,test_5@gmail.com,15098765432,2021-08-01 14:17:16.551384+00:00,admin_2,yaozeliang,2021-08-02 17:47:27.412336+00:00,79db64d6-464c-4b7d-98d9-6abee69fc0a7,79db64d6,2022-08-02 17:47:27.412336+00:00 +6,test_m6,27,f,London,test_m6@outlook.com,13245678909,2021-08-01 14:21:08.023026+00:00,admin_2,yaozeliang,2021-08-01 20:57:48.899682+00:00,87ec4380-a2fd-4b95-8afb-02aaefbd25d0,87ec4380,2022-08-01 20:57:48.898720+00:00 +7,test_m5,14,f,Milan,test_m5@outlook.com,12344444444,2021-08-02 09:50:39.224378+00:00,yaozeliang,,2021-08-02 09:50:39.229376+00:00,38dfcba4-8e97-4c99-a626-05cc704191df,38dfcba4,2022-08-02 09:50:39.228383+00:00 +8,John Brown,20,m,New York,john@outlook.com,12344456768,2021-08-03 13:54:39.777705+00:00,yaozeliang,,2021-08-03 13:54:39.784316+00:00,5ab5d17b-60da-4bc4-af8b-c5c88c88d984,5ab5d17b,2022-08-03 13:54:39.784316+00:00 +9,John Johnson,20,m,Salt City,john.johnson@outlook.com,130000000987,2021-08-03 13:55:14.516689+00:00,yaozeliang,,2021-08-03 13:55:14.519571+00:00,dc70ce69-40e4-4f75-a951-402fe129198d,dc70ce69,2022-08-03 13:55:14.518522+00:00 +10,Andrew Green,20,m,L.A,andrew.green@gmail.com,13000009283,2021-08-03 13:56:03.567085+00:00,yaozeliang,,2021-08-03 13:56:03.570349+00:00,8a57f31d-6a68-4994-9298-15f5c3dc5f8d,8a57f31d,2022-08-03 13:56:03.569342+00:00 +11,Claire Andson,33,f,New York,claire@outlook.com,13777777777,2021-08-03 20:18:31.155942+00:00,yaozeliang,,2021-08-03 20:18:31.159950+00:00,aeeb057c-21ec-4347-a4d3-ad5175c79208,aeeb057c,2022-08-03 20:18:31.159950+00:00 +12,Emilia,17,f,ShangHai,Emilia@outlook.com,13777777790,2021-08-04 18:49:13.675771+00:00,admin_1,yaozeliang,2021-08-05 13:02:42.481578+00:00,b25009d3-9722-4a74-a128-b211a9a3e469,b25009d3,2022-08-05 13:02:42.480578+00:00 +13,anderson green,54,m,New York,anderson@gmail.com,13700000000,2021-08-05 14:06:12.391822+00:00,yaozeliang,,2021-08-05 14:06:12.395828+00:00,49e3c367-1eca-4eb7-9d68-98a51faa81ac,49e3c367,2022-08-05 14:06:12.395828+00:00 +14,test_m99,20,f,New York,test_m99@gmail.com,13700000000,2021-08-09 17:38:05.664814+00:00,admin_1,,2021-08-09 17:38:05.670814+00:00,542f2651-6037-41cc-9e49-a2f051c25692,542f2651,2022-08-09 17:38:05.669819+00:00 +15,test_100,20,m,Beijing,test_100@gmail.com,13500000000,2021-08-12 13:39:02.192884+00:00,admin_1,,2021-08-12 13:39:02.197888+00:00,f64e12fc-6e75-492d-bb94-4c5b08e8c348,f64e12fc,2022-08-12 13:39:02.197888+00:00 +16,Last Member,20,m,Shanghai,last@outlook.com,13777777777,2021-08-13 13:41:11.579199+00:00,yaozeliang,,2021-08-13 13:41:11.634321+00:00,0dbad35a-e15e-4315-a5e6-6406ea7b90fb,0dbad35a,2022-08-13 13:41:11.633322+00:00 +19,Lousen,20,m,Paris,Lousen@outlook.com,13600000000,2021-08-29 18:56:57.489649+00:00,admin_1,,2021-08-29 18:56:57.493652+00:00,ef5096be-bbce-4949-bf4e-295541d08d0b,ef5096be,2022-08-29 18:56:57.492650+00:00 +20,Septemper User,20,m,London,sep@outlook.com,13777777777,2021-09-01 08:52:53.505031+00:00,yaozeliang,,2021-09-01 08:52:53.508074+00:00,22dbc650-f81c-4526-b6ea-0e80bf0eb936,22dbc650,2022-09-01 08:52:53.508074+00:00 +21,ooo,45,m,Paris,ooo@outlook.com,11111111111,2021-09-06 22:35:28.790202+00:00,yaozeliang,yaozeliang,2021-09-06 22:40:29.610185+00:00,d80eb971-83b3-4d6c-b267-90cc66678d25,d80eb971,2022-09-06 22:40:29.610185+00:00 diff --git a/datacenter/Publisher_20210908.csv b/datacenter/Publisher_20210908.csv new file mode 100644 index 00000000..90c1e187 --- /dev/null +++ b/datacenter/Publisher_20210908.csv @@ -0,0 +1,7 @@ +id,name,city,contact,created_at,updated_by,updated_at +1,Pub1,Paris,people@outlook.com,2021-07-31 18:21:19.128665+00:00,yaozeliang,2021-07-31 18:21:19.129664+00:00 +2,Pub2,Beijing,FakePub2@outlook.com,2021-07-31 18:21:27.033171+00:00,yaozeliang,2021-07-31 18:21:27.034167+00:00 +3,Pub3,Rome,FakePub3@outlook.com,2021-07-31 18:21:36.376148+00:00,yaozeliang,2021-07-31 18:21:36.376148+00:00 +4,Pub4,Tokyo,FakePub4@163.com,2021-07-31 18:21:53.540765+00:00,yaozeliang,2021-08-01 15:14:28.407599+00:00 +5,Fake Pub 5,Paris,FakePub5@outlook.com,2021-08-05 10:03:22.230909+00:00,yaozeliang,2021-08-16 17:06:11.552131+00:00 +11,Fake Pub 99,Paris,a@gmail.com,2021-08-29 20:57:26.189029+00:00,yaozeliang,2021-08-29 20:57:26.200985+00:00 diff --git a/db.sqlite3 b/db.sqlite3 index ede02ba1..74a55e15 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/INSTALLER b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/METADATA b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/METADATA new file mode 100644 index 00000000..a9ed42f7 --- /dev/null +++ b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/METADATA @@ -0,0 +1,271 @@ +Metadata-Version: 2.1 +Name: django-flatpickr +Version: 1.0.1 +Summary: Flatpickr based DatePickerInput, TimePickerInput and DateTimePickerInput with date-range-picker functionality for django >= 2.0 +Home-page: https://github.com/monim67/django-flatpickr +Author: Munim Munna +Author-email: monim67@yahoo.com +License: MIT +Keywords: django flatpickr date-picker time-picker datetime-picker date-range-picker +Platform: UNKNOWN +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Classifier: Environment :: Web Environment +Classifier: Operating System :: OS Independent +Classifier: License :: OSI Approved :: MIT License +Classifier: Development Status :: 5 - Production/Stable +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Framework :: Django +Classifier: Framework :: Django :: 2.1 +Classifier: Framework :: Django :: 2.0 +Requires-Python: >=3.4 +Requires-Dist: django (>=2.0) + +django-flatpickr +================ + +This django widget contains Date-Picker, Time-Picker, DateTime-Picker input +widgets with date-range-picker functionality for django version >= 2.0. +The widget implements `flatpickr `_ +to display date-pickers in django model forms and custom forms which can be +configured easily for date-range selection. For Bootstrap date-picker see +`django-bootstrap-datepicker-plus `_. + + +| |ci-status| |coverage.io| +| |pyversions| |djversions| |pypi-version| +| |format| |status| |license| + +| |flatpickr-red-theme| |flatpickr-default-theme| |flatpickr-dark-theme| + + + +Demo +---- +- `Custom Form `_. +- `Model Form `_. +- `Generic View (without Model Form) `_. + + + +Getting Started +--------------- + + +Prerequisites +^^^^^^^^^^^^^ +- Python >= 3.4 +- Django >= 2.0 + + +Installing +^^^^^^^^^^ +Install the PyPI package via pip. + +:: + + pip install django-flatpickr + +Add ``flatpickr`` to ``INSTALLED_APPS`` in your ``settings.py`` file. + +.. code:: python + + INSTALLED_APPS = [ + # Add the following + 'flatpickr', + ] + + + +Usage +----- + +The HTML template must have the following to render the flatpickr widget. +A better example is `here `_. + +.. code:: html + + + {{ form.media }} {# Adds all flatpickr JS/CSS files from CDN #} + {{ form.as_p }} {# Renders the form #} + + +You can use it `with generic views without a model form `_. +It can also be used with custom forms and model forms as below. + + +Usage in Custom Form +^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + # File: forms.py + from flatpickr import DatePickerInput, TimePickerInput, DateTimePickerInput + from .models import Event + from django import forms + + class ToDoForm(forms.Form): + todo = forms.CharField(widget=forms.TextInput()) + date = forms.DateField(widget=DatePickerInput()) + time = forms.TimeField(widget=TimePickerInput()) + datetime = forms.DateTimeField(widget=DateTimePickerInput()) + + + # File: views.py + class CustomFormView(generic.FormView): + template_name = 'myapp/custom-form.html' + form_class = ToDoForm + + +See `models.py `_, `forms.py `_, +`views.py `_, `custom-form.html `_ +for more details. + +Usage in Model Form +^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + # File: forms.py + from flatpickr import DatePickerInput, TimePickerInput, DateTimePickerInput + from .models import Event + from django import forms + + class EventForm(forms.ModelForm): + class Meta: + model = Event + fields = ['name', 'start_date', 'start_time', 'start_datetime'] + widgets = { + 'start_date': DatePickerInput(), + 'start_time': TimePickerInput(), + 'start_datetime': DateTimePickerInput(), + } + + + # File: views.py + class UpdateView(generic.edit.UpdateView): + model = Event + form_class = EventForm + + +See `models.py `_, `forms.py `_, +`views.py `_, `event_form.html `_ +for more details. + +Implement date-range-picker +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +DatePickers can be linked together to select a date-range, time-range or +date-time-range **without writing a single line of JavaScript**. + +.. code:: python + + # File: forms.py + from flatpickr import DatePickerInput, TimePickerInput + from django import forms + + class EventForm(forms.ModelForm): + class Meta: + model = Event + fields = ['name', 'start_date', 'end_date', 'start_time', 'end_time'] + widgets = { + 'start_date':DatePickerInput().start_of('event days'), + 'end_date':DatePickerInput().end_of('event days'), + 'start_time':TimePickerInput().start_of('party time'), + 'end_time':TimePickerInput().end_of('party time'), + } + + + +Customization +------------- + +To customize the look and features of flatpickr widget copy the +`settings block `_ to your settings.py file and customize it. +Settings applies globally to all flatpickr widgets used in your site. + +If you need to customize a single flatpickr widget you can do it as follows: + +.. code:: python + + class ToDoForm(forms.Form): + todo = forms.CharField(widget=forms.TextInput()) + date = forms.DateField(widget=DatePickerInput( + attrs = { # input element attributes + "class": "my-custom-class", + }, + options = { # flatpickr options + "dateFormat": "m/d/Y", + } + )) + + + +License +------- + + - `MIT LICENSE `_. + - `CONTRIBUTING `_. + - `CODE_OF_CONDUCT `_. + + +.. |flatpickr-red-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549374/3cc01102-028d-11e6-9ff4-0cf208a310c4.PNG + :alt: Flatpickr Red Theme + +.. |flatpickr-default-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549370/3cadb750-028d-11e6-818d-c6a1bc6349fc.PNG + :alt: Flatpickr Default Theme + +.. |flatpickr-dark-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549372/3cbc8514-028d-11e6-8daf-ec1ba01c9d7e.PNG + :alt: Flatpickr Dark Theme + + +.. |ci-status| image:: https://travis-ci.org/monim67/django-flatpickr.svg?branch=master + :target: https://travis-ci.org/monim67/django-flatpickr + :alt: Build Status + +.. |coverage.io| image:: https://coveralls.io/repos/github/monim67/django-flatpickr/badge.svg?branch=master + :target: https://coveralls.io/github/monim67/django-flatpickr?branch=master + :alt: Coverage Status + +.. |pyversions| image:: https://img.shields.io/pypi/pyversions/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: Python Versions + +.. |djversions| image:: https://img.shields.io/pypi/djversions/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: DJango Versions + +.. |pypi-version| image:: https://badge.fury.io/py/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: PyPI version + +.. |format| image:: https://img.shields.io/pypi/format/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: Format + +.. |status| image:: https://img.shields.io/pypi/status/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: Status + +.. |license| image:: https://img.shields.io/pypi/l/django-flatpickr.svg + :target: https://pypi.python.org/pypi/django-flatpickr + :alt: Licence + + +.. _demo_custom_form: https://monim67.github.io/django-flatpickr/demo/custom-form.html +.. _demo_model_form: https://monim67.github.io/django-flatpickr/demo/generic-view-with-model-form-1.html +.. _demo_generic_view: https://monim67.github.io/django-flatpickr/demo/generic-view.html + +.. _generic_view_block: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/views.py#L11 +.. _settings_block: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/mysite/settings.py#L134-L176 + +.. _file_custom_form_html: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/templates/myapp/custom-form.html +.. _file_event_form_html: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/templates/myapp/event_form.html +.. _file_forms_py: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/forms.py +.. _file_views_py: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/views.py +.. _file_models_py: https://github.com/monim67/django-flatpickr/blob/v1.0.0/dev/myapp/models.py + + + diff --git a/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/RECORD b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/RECORD new file mode 100644 index 00000000..5d6b798d --- /dev/null +++ b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/RECORD @@ -0,0 +1,19 @@ +django_flatpickr-1.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +django_flatpickr-1.0.1.dist-info/METADATA,sha256=qfDAvN744DLGXxp0KOxIP2C0-Buw3ILR7N9BQfs9Wlw,9024 +django_flatpickr-1.0.1.dist-info/RECORD,, +django_flatpickr-1.0.1.dist-info/WHEEL,sha256=cScVKDQXc_cp1jHmxFDq9fIOIg17a2BsmfS6J39H6Eo,97 +django_flatpickr-1.0.1.dist-info/top_level.txt,sha256=uegOOaxOleprWexYGm_6Ho9AGQA1DX2gdwY47OjfeOQ,10 +flatpickr/__init__.py,sha256=ZFDnKiJ8kyzRtpqxkEkXlD_GnEIFe08IUrVivPz9f-c,1783 +flatpickr/__pycache__/__init__.cpython-38.pyc,, +flatpickr/__pycache__/_base.cpython-38.pyc,, +flatpickr/__pycache__/_config.cpython-38.pyc,, +flatpickr/__pycache__/_helpers.cpython-38.pyc,, +flatpickr/__pycache__/_media.cpython-38.pyc,, +flatpickr/__pycache__/_settings.cpython-38.pyc,, +flatpickr/__pycache__/utils.cpython-38.pyc,, +flatpickr/_base.py,sha256=PqjofP0Za_ICJF2a0OLBc44NB-k5j5SEv88Jku06uf4,2178 +flatpickr/_config.py,sha256=QDRu4mI9THUqcAVK0GeCs8JIzjTPSw7zwjEk71z1fgs,1154 +flatpickr/_helpers.py,sha256=r3j1Cs_H9hIT74wWGPK6Fp8Ilv6SBxtJ8lH3yhAqmXI,961 +flatpickr/_media.py,sha256=Qo9WR39cXECse_WWlrOx_as7cwopB4W_2GBzl28rKcg,1043 +flatpickr/_settings.py,sha256=YTO68IW8wosCk6ilh618mGJcCcxJJ3EoC4Knaqz7LPU,390 +flatpickr/utils.py,sha256=4AoR2dLmiL6cAj8HoZGEO5XX8VHqlggafIfjaQl9iIE,597 diff --git a/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/WHEEL b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/WHEEL new file mode 100644 index 00000000..bff023ed --- /dev/null +++ b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/top_level.txt b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/top_level.txt new file mode 100644 index 00000000..90cd842e --- /dev/null +++ b/env/Lib/site-packages/django_flatpickr-1.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +flatpickr diff --git a/env/Lib/site-packages/flatpickr/__init__.py b/env/Lib/site-packages/flatpickr/__init__.py new file mode 100644 index 00000000..b05b4892 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/__init__.py @@ -0,0 +1,70 @@ +"""This module contains the widget classes.""" + +from flatpickr._base import BasePickerInput + + +__all__ = ( + 'DatePickerInput', + 'TimePickerInput', + 'DateTimePickerInput', +) + + +class DatePickerInput(BasePickerInput): + """ + Widget for DateField to display a Date-Picker Calendar. + + Args: + - attrs (dict): HTML attributes of rendered HTML input + - options (dict): Options to customize the widget, see Docs + """ + + picker_type = 'DATE' + datetime_format = '%Y-%m-%d' + format_key = 'DATE_INPUT_FORMATS' + option_overrides = { + 'mode': 'single', + 'dateFormat': 'Y-m-d', + 'altInput': True, + } + + +class TimePickerInput(BasePickerInput): + """ + Widget for TimeField to display a Time-Picker Calendar. + + Args: + - attrs (dict): HTML attributes of rendered HTML input + - options (dict): Options to customize the widget, see Docs + """ + + picker_type = 'TIME' + datetime_format = '%H:%M:%S' + format_key = 'TIME_INPUT_FORMATS' + option_overrides = { + 'mode': 'single', + 'dateFormat': 'H:i:S', + 'altInput': True, + 'enableTime': True, + 'noCalendar': True, + } + + +class DateTimePickerInput(BasePickerInput): + """ + Widget for DateTimeField to display a DateTime-Picker Calendar. + + Args: + - attrs (dict): HTML attributes of rendered HTML input + - options (dict): Options to customize the widget, see Docs + """ + + picker_type = 'DATETIME' + datetime_format = '%Y-%m-%d %H:%M:%S' + format_key = 'DATETIME_INPUT_FORMATS' + option_overrides = { + 'mode': 'single', + 'dateFormat': 'Y-m-d H:i:S', + 'altInput': True, + 'enableTime': True, + } diff --git a/env/Lib/site-packages/flatpickr/_base.py b/env/Lib/site-packages/flatpickr/_base.py new file mode 100644 index 00000000..f11a62a2 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/_base.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +"""Contains Base Date-Picker input class for widgets of this package.""" + +from django.forms.widgets import DateTimeBaseInput +from flatpickr._settings import WidgetSettings +from flatpickr._media import WidgetMedia +from flatpickr._config import WidgetConfig + + +class BasePickerInput(DateTimeBaseInput): + """Base Date-Picker input class for widgets of this package.""" + + Media = WidgetMedia + picker_type = 'DATE' + datetime_format = '%Y-%m-%d' + format_key = 'DATE_INPUT_FORMATS' + option_overrides = { + 'dateFormat': 'Y-m-d', + } + + def __init__(self, attrs=None, options=None): + """Initialize the Date-picker widget.""" + self.config = WidgetConfig(self.picker_type) + self.config._calculate_options(options, self.option_overrides) + self.template_name = WidgetSettings.TEMPLATE_NAME or self.template_name + _attrs = WidgetSettings.ATTRS.copy() + _attrs.update(attrs or {}) + super().__init__(_attrs, self.datetime_format) + + def get_context(self, name, value, attrs): + """Return widget context dictionary.""" + context = super().get_context( + name, value, attrs) + context['widget']['attrs']['fp_config'] = self.config.to_json() + return context + + def start_of(self, event_id): + """ + Set Date-Picker as the start-date of a date-range. + + Args: + - event_id (string): User-defined unique id for linking two fields + """ + WidgetConfig.events[str(event_id)] = self + return self + + def end_of(self, event_id, import_options=True): + """ + Set Date-Picker as the end-date of a date-range. + + Args: + - event_id (string): User-defined unique id for linking two fields + """ + event_id = str(event_id) + if event_id in WidgetConfig.events: + linked_picker = WidgetConfig.events[event_id] + self.config.linked_to = linked_picker.config.id + else: + raise KeyError( + 'start-date not specified for event_id "%s"' % event_id) + return self diff --git a/env/Lib/site-packages/flatpickr/_config.py b/env/Lib/site-packages/flatpickr/_config.py new file mode 100644 index 00000000..f9f6ba39 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/_config.py @@ -0,0 +1,35 @@ +from flatpickr._helpers import JSONSerializable +from flatpickr._settings import WidgetSettings + + +class WidgetConfig(JSONSerializable): + """Keeps track of all date-picker input classes.""" + + id = None + picker_type = None + linked_to = None + options = None + _json_keys = ['id', 'picker_type', 'linked_to', 'options'] + + _index = 0 + events = dict() + + @classmethod + def generate_id(cls): + """Return a unique ID for each date-picker input class.""" + cls._index += 1 + return 'fp_%s' % cls._index + + def __init__(self, picker_type): + self.id = self.__class__.generate_id() + self.picker_type = picker_type + + def _calculate_options(self, options, option_overrides): + """Calculate and Return the options.""" + _options = {} + _options.update(WidgetSettings.OPTIONS) + _options.update(options if isinstance(options, dict) else {}) + if 'dateFormat' in _options and 'altFormat' not in _options: + _options['altFormat'] = _options.pop('dateFormat') + _options.update(option_overrides) + self.options = _options diff --git a/env/Lib/site-packages/flatpickr/_helpers.py b/env/Lib/site-packages/flatpickr/_helpers.py new file mode 100644 index 00000000..39742f4a --- /dev/null +++ b/env/Lib/site-packages/flatpickr/_helpers.py @@ -0,0 +1,29 @@ +"""Contains the helper classes and methods used throughout the project.""" + +from json import JSONEncoder + + +class JSONSerializer(JSONEncoder): + def default(self, obj): + if hasattr(obj, '_json_keys'): + return {k: getattr(obj, k, None) for k in obj._json_keys} + # else: + # return super().default(obj) + + +class JSONSerializable(JSONEncoder): + def to_json(self): + return JSONSerializer().encode(self) + + +def load_settings(settings_group_name): + """Load settings from settings.py and override defaults.""" + def inner(_class): + from django.conf import settings + if hasattr(settings, settings_group_name): + settings_dict = getattr(settings, settings_group_name) + if isinstance(settings_dict, dict): + for key, value in settings_dict.items(): + setattr(_class, key.upper(), value) + return _class + return inner diff --git a/env/Lib/site-packages/flatpickr/_media.py b/env/Lib/site-packages/flatpickr/_media.py new file mode 100644 index 00000000..57de6423 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/_media.py @@ -0,0 +1,29 @@ +from flatpickr._settings import WidgetSettings + + +class WidgetMedia: + def yield_js(self, settings: WidgetSettings): + yield settings.NPM_URL + 'flatpickr@4.5.2/dist/flatpickr.min.js' + yield ( + settings.GITHUB_URL + + 'monim67/django-flatpickr@1.0.0/static/js/django-flatpickr.js' + ) + if 'locale' in settings.OPTIONS: + yield ( + settings.NPM_URL + + ('flatpickr@4.5.2/dist/l10n/%s.js' % + settings.OPTIONS['locale']) + ) + + def yield_css(self, settings: WidgetSettings): + yield settings.NPM_URL + 'flatpickr@4.5.2/dist/flatpickr.min.css' + if settings.THEME_URL: + yield settings.THEME_URL + elif settings.THEME_NAME: + yield ( + settings.NPM_URL + + ('flatpickr@4.5.2/dist/themes/%s.css' % settings.THEME_NAME) + ) + + js = tuple(yield_js(None, WidgetSettings)) + css = {'all': tuple(yield_css(None, WidgetSettings))} diff --git a/env/Lib/site-packages/flatpickr/_settings.py b/env/Lib/site-packages/flatpickr/_settings.py new file mode 100644 index 00000000..71edf0b4 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/_settings.py @@ -0,0 +1,14 @@ +from flatpickr._helpers import load_settings + + +@load_settings('FLATPICKR_SETTINGS') +class WidgetSettings: + """ Settings can be overriden by FLATPICKR_SETTINGS in settings.py.""" + + THEME_NAME = None + THEME_URL = None + TEMPLATE_NAME = None + ATTRS = {} + OPTIONS = {} + NPM_URL = 'https://cdn.jsdelivr.net/npm/' + GITHUB_URL = 'https://cdn.jsdelivr.net/gh/' diff --git a/env/Lib/site-packages/flatpickr/utils.py b/env/Lib/site-packages/flatpickr/utils.py new file mode 100644 index 00000000..dcffde01 --- /dev/null +++ b/env/Lib/site-packages/flatpickr/utils.py @@ -0,0 +1,19 @@ +from django.forms.models import modelform_factory + + +class GenericViewWidgetMixin: + """ + Enables widgets property in django generic view classes. + + usage: + class CreateView(GenericViewWidgetMixin, generic.edit.CreateView): + model = MyModel + fields = ['field1', 'field2'] + widgets = { + 'field1': widget1(), + 'field2': widget2(), + } + """ + def get_form_class(self): + return modelform_factory(self.model, fields=self.fields, + widgets=self.widgets) diff --git a/media/profile/20210907/4.jpg b/media/profile/20210907/4.jpg new file mode 100644 index 00000000..e808c755 Binary files /dev/null and b/media/profile/20210907/4.jpg differ diff --git a/media/profile/20210907/4_JZzHOdC.jpg b/media/profile/20210907/4_JZzHOdC.jpg new file mode 100644 index 00000000..e808c755 Binary files /dev/null and b/media/profile/20210907/4_JZzHOdC.jpg differ diff --git a/media/profile/20210907/cartoon_1.jpg b/media/profile/20210907/cartoon_1.jpg new file mode 100644 index 00000000..a6d4e746 Binary files /dev/null and b/media/profile/20210907/cartoon_1.jpg differ diff --git a/media/profile/20210907/cartoon_2.jpg b/media/profile/20210907/cartoon_2.jpg new file mode 100644 index 00000000..2bf585e3 Binary files /dev/null and b/media/profile/20210907/cartoon_2.jpg differ diff --git a/media/profile/20210907/cartoon_3.jpg b/media/profile/20210907/cartoon_3.jpg new file mode 100644 index 00000000..343795ed Binary files /dev/null and b/media/profile/20210907/cartoon_3.jpg differ diff --git a/media/profile/20210907/cartoon_4.jpg b/media/profile/20210907/cartoon_4.jpg new file mode 100644 index 00000000..90bb7779 Binary files /dev/null and b/media/profile/20210907/cartoon_4.jpg differ diff --git a/templates/book/book_detail.html b/templates/book/book_detail.html index 3cdef462..30b8cc26 100644 --- a/templates/book/book_detail.html +++ b/templates/book/book_detail.html @@ -67,6 +67,7 @@
Detail : << {{book.title}} >>

Author: {{book.author}}

Category: {{book.category}}

Publisher: {{book.publisher}}

+

Quantity: {{book.quantity}}

diff --git a/templates/borrow_records/create.html b/templates/borrow_records/create.html index 9000e384..aa782c9a 100644 --- a/templates/borrow_records/create.html +++ b/templates/borrow_records/create.html @@ -69,13 +69,22 @@
Add New Record
source: "{% url 'auto_book_name' %}", }); -$("#id_start_day").datetimepicker( { - format:'Y-m-d', - }); +// $("#id_start_day").datetimepicker( { +// // format:'Y-m-d H:i', +// // dateFormat: "yy-mm-dd H:i:ss" + +// }); + +// $("#id_end_day").datetimepicker(); + +// $(".datepicker").datepicker( +// { +// dateFormat: "yy-mm-dd", +// changeYear:true, +// changeMonth:true, +// } +// ) - $("#id_end_day").datetimepicker( { - format:'Y-m-d', - }); } );