Thursday, 30 May 2019
django 40 django + react reference
reference:
https://css-tricks.com/snippets/css/using-font-face/
https://react-icons.netlify.com/#/
django allow cors
https://stackoverflow.com/questions/35760943/how-can-i-enable-cors-on-django-rest-framework
http://chuanshuoge2.blogspot.com/2019/05/django-38-rest-framework-authentication.html
https://chuanshuoge2.blogspot.com/2018/12/bank-react-redux-express-mongodb-heroku.html
https://chuanshuoge2.blogspot.com/2018/05/react-redux.html
Sunday, 26 May 2019
django 39 rest framework filter by url parameter
get request to http://127.0.0.1:8000/api/album_list/?author=chuanshuo&data_length=2
server returns 2 of chuanshuo's posts
#music/api/apiview
from music.api.serializers import MusicSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
class AlbumList(APIView):
def get(self, request, format=None):
username = request.GET.get('author')
data_length = request.GET.get('data_length')
#filter by author
if username==None:
albums = Album.objects.all()
else:
author_id = get_object_or_404(User, username=username).pk
albums = Album.objects.filter(author=author_id).order_by('-date_posted')
#filter by data length
if data_length!=None:
try:
int(data_length)
except ValueError:
return Response('data length is invvalid', status=status.HTTP_406_NOT_ACCEPTABLE)
else:
albums = albums[:int(data_length)]
serializer = MusicSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MusicSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = MusicSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
#only owner can edit
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status= status.HTTP_403_FORBIDDEN)
serializer = MusicSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
# only owner can delete
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status=status.HTTP_403_FORBIDDEN)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
reference:
https://pypi.org/project/django-filter/
https://www.django-rest-framework.org/api-guide/status-codes/
https://stackoverflow.com/questions/25928990/catching-any-doesnotexist-error
https://chuanshuoge2.blogspot.com/2019/05/django-38-rest-framework-authentication.html
Saturday, 25 May 2019
Wednesday, 22 May 2019
django 38 rest framework token authentication
get from http://127.0.0.1:8000/api/album_list/, response credential not provided
post to http://127.0.0.1:8000/api/api-token-auth/ with login, obtain token
get request to http://127.0.0.1:8000/api/album_list/ with token, server responds with data
send put request to http://127.0.0.1:8000/api/album_detail/38/ to edit chuanshuo's post but with bob's token
server responds permission denied
post request to http://127.0.0.1:8000/api/api-token-auth/ with chuanshuo's login
obtain chanshuo's token
send put request to http://127.0.0.1:8000/api/album_detail/38/ with chuanshuo's token to edit his own post, successful
#settings
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
]
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken',
]
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
}
#powershell
python manage.py migrate
------------------------------
#music/api/urls
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from music.api import apiview, mixins
from rest_framework.authtoken import views
app_name = 'musicAPI'
urlpatterns = [
path('album_list/', apiview.AlbumList.as_view(), name='AlbumList'),
path('album_detail/<int:pk>/', apiview.AlbumDetail.as_view(), name='AlbumDetail'),
path('album_list_mixin/', mixins.AlbumListMixin.as_view(), name='AlbumListMixin'),
path('album_detail_mixin/<int:pk>/', mixins.AlbumDetailMixin.as_view(), name='AlbumDetailMixin'),
path('api-token-auth/', views.obtain_auth_token, name='AuthToken'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
-----------------------------------------------------
#music/api/apiview
from music.models import Album
from music.api.serializers import MusicSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
class AlbumList(APIView):
def get(self, request, format=None):
albums = Album.objects.all()
serializer = MusicSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MusicSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = MusicSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
#only owner can edit
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status= status.HTTP_403_FORBIDDEN)
serializer = MusicSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
# only owner can delete
if album.author != request.user:
return Response({"detail": "You do not have permission to perform this action."},
status=status.HTTP_403_FORBIDDEN)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
-----------------------------------------
#music/api/mixins
from music.models import Album
from music.api.serializers import MusicSerializer
from rest_framework import mixins, generics, permissions
from .permissions import IsOwnerOrReadOnly
class AlbumListMixin(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Album.objects.all()
serializer_class = MusicSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class AlbumDetailMixin(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Album.objects.all()
serializer_class = MusicSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
------------------------------------
#music/api/permisions
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
# Write permissions are only allowed to the owner of the snippet.
return obj.author == request.user
reference:
https://www.youtube.com/watch?v=PFcnQbOfbUU&list=PLbpAWbHbi5rMV3H0S5IDK3cSRC1Jas3VP&index=3
https://stackoverflow.com/questions/39923384/str-object-is-not-callable-django-rest-framework
https://stackoverflow.com/questions/53649252/django-rest-framework-basepermissionmetaclass-object-is-not-iterable
http://chuanshuoge2.blogspot.com/2019/05/django-37-rest-framework-class-based.html
http://chuanshuoge2.blogspot.com/2019/05/django-36-rest-framework-class-based.html
Monday, 20 May 2019
django 37 rest framework class based mixins
get from http://127.0.0.1:8000/api/album_list_mixin
postman posts to http://127.0.0.1:8000/api/album_list_mixin
post successful, new id =35
postman get from http://127.0.0.1:8000/api/album_detail_mixin/35/
postman send put request to http://127.0.0.1:8000/api/album_detail_mixin/35/ to change artist to 'new postman'
artist is changed, put request is successful
postman send delete request to http://127.0.0.1:8000/api/album_detail_mixin/35/
delete request is successful
#music/api/mixins
from music.api.serializers import MusicSerializer
from rest_framework import mixins
from rest_framework import generics
class AlbumListMixin(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Album.objects.all()
serializer_class = MusicSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class AlbumDetailMixin(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Album.objects.all()
serializer_class = MusicSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
--------------------------------------
#music/api/urls
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from music.api import apiview, mixins
app_name = 'musicAPI'
urlpatterns = [
path('album_list', apiview.AlbumList.as_view(), name='AlbumList'),
path('album_detail/<int:pk>/', apiview.AlbumDetail.as_view(), name='AlbumDetail'),
path('album_list_mixin', mixins.AlbumListMixin.as_view(), name='AlbumListMixin'),
path('album_detail_mixin/<int:pk>/', mixins.AlbumDetailMixin.as_view(), name='AlbumDetailMixin')
]
urlpatterns = format_suffix_patterns(urlpatterns)
reference:
https://chuanshuoge2.blogspot.com/2019/05/django-35-rest-framework-apiview-get.html
Sunday, 19 May 2019
django 36 rest framework class based apiview put delete
get details from http://127.0.0.1:8000/api/album_detail/33/
post send put request to http://127.0.0.1:8000/api/album_detail/33/ to change genre to 'rock'
get details from http://127.0.0.1:8000/api/album_detail/33/ genre is changed to 'rock'
postman send delete requent to http://127.0.0.1:8000/api/album_detail/33/
album no longer exist
#music/api/apiview
from music.models import Album
from music.api.serializers import MusicSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
class AlbumList(APIView):
def get(self, request, format=None):
albums = Album.objects.all()
serializer = MusicSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MusicSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = MusicSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
serializer = MusicSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
-----------------------------------------------
#music/api/urls
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from music.api import apiview
app_name = 'musicAPI'
urlpatterns = [
path('album_list', apiview.AlbumList.as_view(), name='AlbumList'),
path('album_detail/<int:pk>/', apiview.AlbumDetail.as_view(), name='AlbumDetail'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
reference:
Saturday, 18 May 2019
Friday, 17 May 2019
HIDDEN Fees When Purchasing a House
Home inspection $500
before closing
Appraisal fee $450
before closing after contract
Earnest money deposit 1.5%
- 3% of sales price before closing
Title insurance $2000
paid at closing
County transfer tax $350
paid at closing
State transfer tax 0.0025*
sales price paid at closing
State mortgage tax 0.0025
* mortgage amount
Property tax paid
at closing
Homeowner’s insurance $1000
paid at closing
HOA transfer fee $300
paid at closing
Title services $550
paid at closing
Condo move-in fee $100
- $300 paid at closing
reference:
https://www.youtube.com/watch?v=K3o4rwczZy0
https://www.youtube.com/watch?v=_1fTFZEB3BQ
Thursday, 16 May 2019
django 35 rest framework class based apiview get post
get request to http://127.0.0.1:8000/api/album_list, last id = 32
postman post request to http://127.0.0.1:8000/api/album_list, new id = 33
verify data posted to server
#music/api/apiview
from music.api.serializers import MusicSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class AlbumList(APIView):
def get(self, request, format=None):
albums = Album.objects.all()
serializer = MusicSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = MusicSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
------------------------------------------------
#music/api/urlsfrom django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from music.api import apiview
app_name = 'musicAPI'
urlpatterns = [
path('album_list', apiview.AlbumList.as_view(), name='AlbumList'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
-------------------------------------
#project1/urls
urlpatterns = [
...
path('api/', include('music.api.urls')),
]
-------------------------------------
#music/api/serializers
from rest_framework import serializers
from music.models import Album
class MusicSerializer(serializers.ModelSerializer):
class Meta:
model = Album
fields = ('id', 'artist', 'album_title', 'genre', 'album_logo', 'date_posted', 'author')
reference:
http://chuanshuoge2.blogspot.com/2019/05/django-34-restful-api.html
Wednesday, 15 May 2019
django 34 rest framework viewset get
postman get last 5 albums from http://127.0.0.1:8000/api/albums_last5/
postman get all albums from http://127.0.0.1:8000/api/albums_all/
#powershell
pip install djangorestframework
------------------------------
#settings
INSTALLED_APPS = [
...
'rest_framework',
]
---------------------------------
#music/api/serializers
from rest_framework import serializers
from music.models import Album
class MusicSerializer(serializers.ModelSerializer):
class Meta:
model = Album
fields = ('id', 'artist', 'album_title', 'genre', 'album_logo', 'date_posted', 'author')
---------------------------------
#music/api/viewsets
from music.models import Album
from .serializers import MusicSerializer
from rest_framework import viewsets
class AlbumAllViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = MusicSerializer
http_method_names = ['get']
class AlbumLast5ViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all().order_by('-date_posted')[:5]
serializer_class = MusicSerializer
http_method_names = ['get']
-------------------------------------
#project1/router
from music.api.viewsets import AlbumLast5ViewSet, AlbumAllViewSet
from rest_framework import routers
router = routers.DefaultRouter()
router.register('albums_all', AlbumAllViewSet)
router.register('albums_last5', AlbumLast5ViewSet)
----------------------------
#project1/urls
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from .router import router
urlpatterns = [
path('admin/', admin.site.urls),
path('music/', include('music.urls')),
path('', include('django.contrib.auth.urls')),
path('api/', include(router.urls)),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
reference:
http://chuanshuoge2.blogspot.com/2019/05/django-34-restful-api.html
Wednesday, 8 May 2019
tri-cities trip
expense
May 8 - taxi, delta luggage, rental carMay 9 - hotel
May 10 - taxi
May 13 - train ticket, taxi
timesheet
May 8 - ferry to tri-cities 12h
May 9 - bundle, ferry to new york 12h
May 10 - weather down 8h
May 9 - bundle, ferry to new york 12h
May 10 - weather down 8h
May 11 - survey 12h
May12 - weather down 8h
May 13 - ferry back 8h
May12 - weather down 8h
May 13 - ferry back 8h
Monday, 6 May 2019
django 34 restful api reference
reference:
https://www.youtube.com/watch?v=ejJ-2oz4AgI
https://www.youtube.com/watch?v=riZYgLOYq4g
https://www.django-rest-framework.org/
https://stackoverflow.com/questions/23639113/disable-a-method-in-a-viewset-django-rest-framework
https://stackoverflow.com/questions/16015548/tool-for-sending-multipart-form-data-request
Sunday, 5 May 2019
django 33 reset password by email
click reset password
enter email address, django looks through users' record. If match is found, reset email will be sent.
if email is same with others, django sends email to user registered first. make sure email is unique.
notification email is sent
mail box receives email, click the link
enter new password
password changed, click log in
log in with new password
log in successful
#project1/urls
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('music/', include('music.urls')),
path('', include('django.contrib.auth.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
#settings
#email setting
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'zchen2014chuanshuo@gmail.com'
EMAIL_HOST_PASSWORD = 'xxx'
----------------------------------------
#templates/registration/password_reset_done
{% block content %}
<p>
We've emailed you instructions for setting your password, if an account exists with the email you entered.
You should receive them shortly.
</p>
<p>
If you don't receive an email, please make sure you've entered the address you registered with,
and check your spam folder.
</p>
{% endblock %}
---------------------------------------
#templates/registration/password_reset_email
{% autoescape off %}
To initiate the password reset process for your {{ user.get_username }} TestSite Account,
click the link below:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
Sincerely,
The TestSite Team
{% endautoescape %}
---------------------------------------
#templates/registration/password_reset_confirm
{% block content %}
{% if validlink %}
<h3>Change password</h3>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Change password</button>
</form>
{% else %}
<p>
The password reset link was invalid, possibly because it has already been used.
Please request a new password reset.
</p>
{% endif %}
{% endblock %}
---------------------------------------------------
#templates/registration/password_reset_complete
{% block content %}
<p>
Your password has been set. You may go ahead and <a href="{% url 'signin' %}">sign in</a> now.
</p>
{% endblock %}
---------------------------------------
#templates/music/login_form
{% extends 'music/base.html' %}
{% block title %}Log in{% endblock %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Log in</legend>
</fieldset>
<div class="form-group">
{{ form|crispy }}
</div>
<div class="form-group">
Don't have an account?
<a href="{% url 'music:register' %}">Register one</a>
</div>
<div class="form-group">
Forgot password? Reset by email.
<a href="{% url 'password_reset' %}">Reset password</a>
</div>
<div class="form-group">
<button class="btn btn-success btn-sm" type="submit">Submit</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
-------------------------------------
#templates/registration/password_reset_subject
TestSite password reset
reference:
https://stackoverflow.com/questions/44676880/error-reverse-for-password-reset-done-not-found-password-reset-done-is-not
https://simpleisbetterthancomplex.com/tutorial/2016/09/19/how-to-create-password-reset-view.html
Friday, 3 May 2019
Thursday, 2 May 2019
django 32 sending email
dynamically add/remove recipients
all recipients receive email
#urls
from django.urls import pathfrom . import views
app_name = 'music'
urlpatterns = [
#music/eamil
path('email/', views.Email.as_view(), name='email'),
]
-------------------------------------
#views
from .forms import SendEmailForm
from django.contrib import messages
from django.core.mail import send_mail
from django.conf import settings
class Email(View):
form_class = SendEmailForm
template_name = 'music/email_form.html'
def get(self, request):
#get request, display Form with empty fields
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
subject = form.data['subject']
message = form.data['message']
email_from = settings.EMAIL_HOST_USER
recipient_list = request.POST.getlist('recipients[]')
send_mail(subject, message, email_from, recipient_list)
messages.success(request, 'emails sent')
return redirect('music:email')
messages.error(request, 'error')
return render(request, self.template_name, {'form': form})
----------------------------------------
#forms
class SendEmailForm(forms.Form):
subject = forms.CharField(widget=forms.TextInput())
message = forms.CharField(widget=forms.Textarea, required=False)
-------------------------------------------
#settings
#email setting
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'zchen2014chuanshuo@gmail.com'
EMAIL_HOST_PASSWORD = 'xxx'
-------------------------------------------
#template/email_form
{% extends 'music/base.html' %}
{% block title %}Email{% endblock %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Send Email</legend>
</fieldset>
<div class="input_fields_wrap form-group">
<label>Recipients</label>
<button class="add_field_button btn-outline-dark">Add more</button><br>
<input type="email" name="recipients[]" required="required">
</div>
<div class="form-group">
{{ form|crispy }}
</div>
<div class="form-group">
<button class="btn btn-success btn-sm" type="submit">Submit</button>
</div>
</form>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><input type="email" name="recipients[]" required="required"/><a href="#" class="remove_field">Remove</a></div>'); //add input box
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
</script>
{% endblock %}
------------------------------------------
#templates/base
<body>
<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://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
....
</body>
reference:
http://chuanshuoge2.blogspot.com/2019/04/django-32-sending-email.html
Wednesday, 1 May 2019
Home Tax Deductions & Tax Credits for Canadian Homeowners
Mortgage not deductible
Tax credit vs. tax income deduction
Tax credits effectively reduce taxes by the entire amount of the credit. For example, in 2009, new home buyers received a first-time homebuyer's credit -- which no longer exists -- of $8,000, which reduced their total tax due by $8,000.By contrast, if you paid $8,000 in mortgage interest for the year, it would not reduce your taxes by that amount. Your taxable income is reduced instead. So if you pay $8,000 in interest and are in the 22 percent tax bracket, your mortgage interest deduction actually reduces your taxes by $1,760, or 22 percent of $8,000.
First-time Home Buyers Tax Credit $5,000. you did not live in another home owned by you or your spouse or common-law partner in the year of acquisition or in any of the four preceding years
GST/HST New Housing/ Rental Property Rebate
landlord who purchased a newly constructed or substantially renovated residential rental property
If you rent real estate or other property, including farmland that you own or have use of, you will need to report the income to the CRA on Form T776, Statement of Real Estate Rentals, which allows you to claim allowable expenses such as advertising, insurance and interest on money you borrow to buy or improve the property.
Home Buyer’s Plan
Homeowners Who Work From Home
Utilities – heating, water and electricity
Insurance
Maintenance
Internet
Office supplies
Cleaning supplies
Moving Expenses
you moved to be a student in full-time attendance in a post-secondary program at a university, college or other educational institution.
To qualify, your new home must be at least 40 kilometres (by the shortest usual public route) closer to your new work or school.
reference:
https://turbotax.intuit.ca/tips/home-tax-deductions-credits-in-canada-5223
https://www.investopedia.com/articles/mortgages-real-estate/08/tax-deductible-mortgage-canada.asp
https://www.moneysense.ca/columns/how-your-home-can-save-you-at-tax-time/
Subscribe to:
Posts (Atom)