Merged upstream master into task/3731/cdist_ssh_key_handler

This commit is contained in:
PCoder 2017-09-09 13:44:41 +05:30
commit f9abdfe1bc
23 changed files with 556 additions and 130 deletions

View file

@ -25,7 +25,7 @@ msgid "Your account is not activated yet."
msgstr "Dein Account wurde noch nicht aktiviert."
msgid "User does not exist"
msgstr ""
msgstr "Der Benutzer existiert nicht"
msgid "Paste here your public key"
msgstr "Füge deinen Public Key ein"
@ -37,7 +37,7 @@ msgid "Key name"
msgstr "Key-Name"
msgid "Please input a proper SSH key"
msgstr ""
msgstr "Bitte verwende einen gültigen SSH-Key"
msgid "My Virtual Machines"
msgstr "Meine virtuellen Maschinen"
@ -362,6 +362,32 @@ msgstr "Deine Kreditkartennummer"
msgid "Reset your password"
msgstr "Passwort zurücksetzen"
msgid "UPDATE"
msgstr ""
msgid "Last"
msgstr ""
msgid "Type"
msgstr "Kartentyp"
msgid "REMOVE CARD"
msgstr "KARTE ENTFERNEN"
msgid "EDIT CARD"
msgstr "BEARBEITEN"
msgid "No Credit Cards Added"
msgstr "Es wurde keine Kreditkarte hinzugefügt"
msgid ""
"We are using <a href=\"https://stripe.com\">Stripe</a> for payment and do "
"not store your information in our database."
msgstr ""
"Wir nutzen <a href="
"\"https://stripe.com\" target=\"_blank\">Stripe</a> für die Bezahlung und "
"speichern keine Informationen in unserer Datenbank."
msgid "Add your public SSH key"
msgstr "Füge deinen öffentlichen SSH-Key hinzu"
@ -519,6 +545,12 @@ msgid ""
"contact Data Center Light Support."
msgstr "Kontaktiere den Data Center Light Support."
#~ msgid "Add a new Card."
#~ msgstr "Neue Kreditkarte hinzufügen."
#~ msgid "You are not making any payment here."
#~ msgstr "Es wird noch keine Bezahlung vorgenommen"
#~ msgid "Your SSH Keys"
#~ msgstr "Deine SSH Keys"

View file

@ -5,13 +5,18 @@
}
.dashboard-container {
padding-top:70px;
padding-top: 80px;
padding-bottom: 70px;
width: 90%;
margin: 0 auto;
max-width: 768px;
}
.dashboard-container.wide {
padding-top: 90px;
max-width: 980px;
}
.content-dashboard{
min-height: calc(100vh - 70px);
width: 80%;
@ -241,6 +246,113 @@
transform: translate(-50%,-50%);
}
.settings-container {
padding: 8px;
}
.settings-container h4 {
margin-bottom: 15px;
color: #333;
font-size: 14px;
}
.settings-container .card-expiry-element,
.settings-container .card-cvc-element {
padding: 0 15px;
}
.settings-container .card-cvc-element .my-input,
.settings-container .card-cvc-element label {
padding-left: 0;
}
.settings-container .stripe-payment-btn {
float: none;
position: static;
}
.settings-container h3 {
font-weight: bold;
}
.settings-container hr {
margin-top: 15px;
}
.settings-container .credit-card-details {
padding-bottom: 15px;
border-bottom: 1px solid #eee;
}
.settings-container .credit-card-details h5 {
font-weight: bold;
font-size: 16px;
}
.credit-card-form {
max-width: 360px;
}
.btn-wide {
min-width: 100px;
}
.caps-link {
font-weight: 600;
color: #8da4c0;
fill: #8da4c0;
padding: 8px 0;
display: block;
}
.caps-link:hover,
.caps-link:focus,
.caps-link:active {
color: #627388;
fill: #627388;
text-decoration: none;
}
.settings-container .credit-card-details-opt {
padding-top: 15px;
}
.caps-link .svg-img {
margin-right: 5px;
height: 13px;
position: relative;
top: 1px;
vertical-align: baseline;
}
.settings-container .caps-link {
font-size: 13px;
letter-spacing: 1.1px;
}
.settings-container .btn-vm-contact {
font-weight: 600;
font-size: 13px;
/* padding: 4px 15px; */
}
.btn-wide {
min-width: 100px;
}
.no-cards {
text-align: center;
color: #999;
padding: 15px;
background: rgba(0,0,0,0.02);
display: flex;
flex-direction: column;
height: 230px;
justify-content: center;
}
.no-cards h4 {
font-size: 24px;
}
.no-cards a {
color: #7ca3d0;
}

View file

@ -34,7 +34,8 @@ h6 {
.navbar-default {
background: #fff;
box-shadow: 0 3px 3px -2px hsla(0,0%,78%,.72);
/* box-shadow: 0 3px 3px -2px hsla(0,0%,78%,.72); */
padding: 5px;
}
.navbar-default .navbar-header {
@ -78,13 +79,20 @@ h6 {
left: 0 !important;
min-width: 155px;
margin-left: 15px;
padding: 5px !important;
padding: 0 5px 8px !important;
}
@media(min-width: 768px) {
.navbar-right .highlights-dropdown .dropdown-menu {
border: 1px solid #fff;
.navbar-default .navbar-nav>li>a,
.navbar-right .highlights-dropdown .dropdown-menu > li > a {
font-weight: 300;
}
.navbar-right .highlights-dropdown .dropdown-menu:before {
.navbar-right .highlights-dropdown .dropdown-menu {
box-shadow: 0 2px 5px 0 rgba(0,0,0,0.02);
border-width: 0 0 1px 0;
border-color: #e7e7e7;
box-shadow: -8px 14px 20px -5px rgba(77, 77, 77, 0.5);
}
/* .navbar-right .highlights-dropdown .dropdown-menu:before {
content: '';
display: block;
height: 1px;
@ -93,13 +101,12 @@ h6 {
top: -1px;
left: -1px;
right: -1px;
}
} */
}
.navbar-right .highlights-dropdown .dropdown-menu > li > a{
font-size: 13px;
font-weight: 300;
font-family: 'Lato', sans-serif;
padding: 1px 10px !important;
padding: 1px 10px 1px 18px !important;
background: transparent;
color: #333;
}
@ -608,6 +615,7 @@ a.unlink:hover {
border: 1px solid #a1a1a1;
border-radius: 3px;
padding: 5px;
margin-bottom: 15px;
}
.card-warning-error {
border: 1px solid #EB4D5C;
@ -765,12 +773,12 @@ a.unlink:hover {
@media (min-width: 768px) {
.dcl-billing {
padding-right: 50px;
padding-right: 65px;
border-right: 1px solid #eee;
}
.dcl-creditcard {
padding-left: 50px;
padding-left: 65px;
}
.tbl-tot {

View file

@ -446,6 +446,11 @@
width: 34px;
vertical-align: middle;
}
.dashboard-title-thin .un-icon.wide {
height: 38px;
width: 38px;
margin-top: -6px;
}
.dashboard-subtitle {
font-weight: 300;
@ -533,6 +538,11 @@
width: 22px;
margin-top: -3px;
}
.dashboard-title-thin .un-icon.wide {
height: 25px;
width: 25px;
margin-top: -5px;
}
.dashboard-subtitle p {
width: 200px;
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><path d="M185,150h630c19.3,0,35-15.7,35-35s-15.7-35-35-35H605c0-38.7-31.3-70-70-70h-70c-38.7,0-70,31.3-70,70H185c-19.3,0-35,15.7-35,35S165.7,150,185,150z"/><path d="M885,220h-69.9c-0.1,0-0.3,0-0.4,0H395.1c0,0-0.1,0-0.1,0H185.3c-0.1,0-0.2,0-0.3,0h-70c-19.3,0-35,15.7-35,35c0,19.3,15.7,35,35,35h39.9l100.5,670.2C258,977.3,272.7,990,290,990h139.9c0,0,0,0,0,0c0,0,0,0,0,0h140c0,0,0,0,0,0c0,0,0,0,0,0H710c17.3,0,32-12.7,34.6-29.8L845.1,290H885c19.3,0,35-15.7,35-35C920,235.7,904.3,220,885,220z M463.3,920l-31.5-630h136.4l-31.5,630H463.3z M225.6,290h136.1l31.5,630h-73.1L225.6,290z M679.9,920h-73.1l31.5-630h136.1L679.9,920z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -73,7 +73,6 @@ $( document ).ready(function() {
* Replace all SVG images with inline SVG
*/
$('.svg-img').each(function() {
console.log('asa')
var $img = $(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');

View file

@ -25,6 +25,8 @@
<link href="{% static 'hosting/css/commons.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/virtual-machine.css' %}" rel="stylesheet">
<link href="{% static 'hosting/css/dashboard.css' %}" rel="stylesheet">
{% block css_extra %}
{% endblock css_extra %}
<!-- Custom Fonts -->
<link href='//fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
@ -51,61 +53,7 @@
{% block navbar %}
<!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
<div class="container topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
{% if request.user.is_authenticated %}
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% endif %}
<a class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
</div>
{% if request.user.is_authenticated %}
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="{% url 'hosting:virtual_machines' %}">
<i class="fa fa-server" aria-hidden="true"></i> {% trans "My Virtual Machines"%}
</a>
</li>
<li>
<a href="{% url 'hosting:orders' %}">
<i class="fa fa-credit-card"></i> {% trans "My Orders"%}
</a>
</li>
<li class="dropdown">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
<i class="glyphicon glyphicon-user"></i> {{request.user.name}} <span class="caret"></span></a>
<ul id="g-account-menu" class="dropdown-menu" role="menu">
<li>
<a href="{% url 'hosting:ssh_keys' %}">
<i class="fa fa-key"></i> {% trans "SSH Keys" %}
</a>
</li>
<li>
<a href="{% url 'hosting:notifications' %}">
<i class="fa fa-bell"></i> {% trans "Notifications "%}
</a>
</li>
<li><a href="{% url 'hosting:logout' %}"><i class="glyphicon glyphicon-lock"></i>{% trans "Logout"%} </a></li>
</ul>
</li>
</ul>
</div>
{% endif %}
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
{% include "hosting/includes/_navbar_user.html" %}
{% endblock navbar %}

View file

@ -32,7 +32,7 @@
<img class="svg-img" src="{% static 'hosting/img/billing.svg' %}">
</div>
</a>
<a href="" class="hosting-dashboard-item">
<a href="{% url 'hosting:settings' %}" class="hosting-dashboard-item">
<h2>{% trans "My Settings" %}</h2>
<div class="hosting-dashboard-image">
<img class="svg-img" src="{% static 'hosting/img/dashboard_settings.svg' %}">

View file

@ -1,10 +1,10 @@
{% load static i18n %}
<nav class="navbar navbar-default topnav navbar-transparent" role="navigation">
<div class="container topnav">
<div class="topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a id="logoWhite" class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
<a id="logoWhite" class="navbar-brand topnav" href="{% url 'datacenterlight:index' %}"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
</div>
</div>
<!-- /.container -->

View file

@ -0,0 +1,52 @@
{% load staticfiles %}
{% load i18n %}
{% load custom_tags %}
<!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
<div class="topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
{% if request.user.is_authenticated %}
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">{% trans "Toggle navigation" %}</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% endif %}
<a class="navbar-brand topnav" href="{% url 'datacenterlight:index' %}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
</div>
{% if request.user.is_authenticated %}
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="{% url 'hosting:dashboard' %}">
<i class="fa fa-fw fa-server" aria-hidden="true"></i>&nbsp;&nbsp;{% trans "Dashboard"%}
</a>
</li>
<li class="dropdown highlights-dropdown">
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
<i class="fa fa-fw fa-user"></i>&nbsp;&nbsp;{{request.user.name}}&nbsp;<span class="fa fa-fw fa-caret-down"></span>
</a>
<ul id="g-account-menu" class="dropdown-menu" role="menu">
<li><a href="{% url 'hosting:logout' %}">{% trans "Logout"%}</a></li>
</ul>
</li>
<li>
{% get_current_language as LANGUAGE_CODE %}
{% if LANGUAGE_CODE == 'en-us'%}
<a href="{% change_lang 'de' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i>&nbsp;&nbsp;Deutsch</a>
{% else %}
<a href="{% change_lang 'en-us' %}"><i class="fa fa-fw fa-globe" aria-hidden="true"></i>&nbsp;&nbsp;English</a>
{% endif %}
</li>
</ul>
</div>
{% endif %}
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>

View file

@ -1,9 +1,12 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 i18n %}
{% block css_extra %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paymentfont/1.1.2/css/paymentfont.min.css"/>
{% endblock css_extra %}
{% block content %}
<!-- Credit card form -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paymentfont/1.1.2/css/paymentfont.min.css"/>
<div class="dcl-order-container">
<div class="payment-container">
<div class="row">

View file

@ -0,0 +1,149 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 i18n %}
{% block css_extra %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paymentfont/1.1.2/css/paymentfont.min.css"/>
{% endblock css_extra %}
{% block content %}
<div class="dashboard-container wide">
<div class="dashboard-container-head">
<h1 class="dashboard-title-thin"><img src="{% static 'hosting/img/dashboard_settings.svg' %}" class="un-icon wide"> {% trans "My Settings" %}</h1>
</div>
<!-- Credit card form -->
<div class="settings-container">
<div class="row">
<div class="col-sm-5 col-md-6 billing dcl-billing">
<h3>{%trans "Billing Address"%}</h3>
<hr>
<form role="form" id="billing-form" method="post" action="" novalidate>
{% for field in form %}
{% csrf_token %}
{% bootstrap_field field show_label=False type='fields' bound_css_class='' %}
{% endfor %}
<div class="form-group text-right">
<button type="submit" class="btn btn-vm-contact btn-wide">{% trans "UPDATE" %}</button>
</div>
</form>
</div>
<div class="col-sm-7 col-md-6 creditcard-box dcl-creditcard">
<h3>{%trans "Credit Card"%}</h3>
<hr>
<div>
{% if credit_card_data.last4 %}
<div class="credit-card-details">
<h5 class="billing-head">{% trans "Credit Card" %}</h5>
<h5 class="membership-lead">{% trans "Last" %} 4: *****{{credit_card_data.last4}}</h5>
<h5 class="membership-lead">{% trans "Type" %}: {{credit_card_data.cc_brand}}</h5>
{% comment %}
<div class="credit-card-details-opt">
<div class="row">
<div class="col-xs-6">
<a class="caps-link" href=""><img src="{% static 'hosting/img/delete.svg' %}" class="svg-img">{% trans "REMOVE CARD" %}</a>
</div>
<div class="col-xs-6 text-right">
<a class="btn btn-vm-contact" href="">{% trans "EDIT CARD" %}</a>
</div>
</div>
</div>
{% endcomment %}
</div>
{% else %}
<div class="no-cards">
<h4>{% trans "No Credit Cards Added" %}</h4>
<p>{% blocktrans %}We are using <a href="https://stripe.com">Stripe</a> for payment and do not store your information in our database.{% endblocktrans %}</p>
</div>
{% comment %}
<h4>{% trans "Add a new Card." %}</h4>
<p style="margin-bottom: 15px;">
{% blocktrans %}Please fill in your credit card information below. We are using <a href="https://stripe.com" target="_blank">Stripe</a> for payment and do not store your information in our database.{% endblocktrans %}
</p>
<form action="" id="payment-form-new" class="credit-card-form" method="POST">
<input type="hidden" name="token"/>
<div class="credit-card-goup">
<div class="card-element card-number-element">
<label>{%trans "Card Number" %}</label>
<div id="card-number-element" class="field my-input"></div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-4 card-element card-expiry-element">
<label>{%trans "Expiry Date" %}</label>
<div id="card-expiry-element" class="field my-input"></div>
</div>
<div class="col-xs-6 col-sm-4 col-sm-offset-4 card-element card-cvc-element">
<label>{%trans "CVC" %}</label>
<div id="card-cvc-element" class="field my-input"></div>
</div>
</div>
<div class="card-element brand">
<label>{%trans "Card Type" %}</label>
<i class="pf pf-credit-card" id="brand-icon"></i>
</div>
</div>
<div id="card-errors" role="alert"></div>
<div>
{% if not messages and not form.non_field_errors %}
<p class="card-warning-content">
{% blocktrans %}You are not making any payment here.{% endblocktrans %}
</p>
{% endif %}
<div id='payment_error'>
{% for message in messages %}
{% if 'failed_payment' or 'make_charge_error' in message.tags %}
<ul class="list-unstyled"><li>
<p class="card-warning-content card-warning-error">{{ message|safe }}</p>
</li></ul>
{% endif %}
{% endfor %}
{% for error in form.non_field_errors %}
<p class="card-warning-content card-warning-error">
{{ error|escape }}
</p>
{% endfor %}
</div>
<div class="row">
<div class="col-xs-6 col-xs-offset-6 text-right">
<button class="btn btn-success stripe-payment-btn" type="submit">{%trans "Submit" %}
</button>
</div>
</div>
</div>
<div style="display:none;">
<p class="payment-errors"></p>
</div>
</form>
{% endcomment %}
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% comment %}
<!-- stripe key data -->
{% if stripe_key %}
{% get_current_language as LANGUAGE_CODE %}
<script type="text/javascript">
window.processing_text = '{%trans "Processing" %}';
window.enter_your_card_text = '{%trans "Enter your credit card number" %}';
(function () {
window.stripeKey = "{{stripe_key}}";
window.current_lan = "{{LANGUAGE_CODE}}";
})();
</script>
{%endif%}
{% if credit_card_data.last4 and credit_card_data.cc_brand %}
<script type="text/javascript">
(function () {
window.hasCreditcard = true;
})();
</script>
{%endif%}
{% endcomment %}
{%endblock%}

View file

@ -1,6 +1,10 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %}
<div class="auth-container">
<div class="auth-bg"></div>

View file

@ -1,6 +1,5 @@
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from .views import (
DjangoHostingView, RailsHostingView, PaymentVMView, NodeJSHostingView,
LoginView, SignupView, SignupValidateView, SignupValidatedView, IndexView,
@ -9,7 +8,9 @@ from .views import (
MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView,
HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView,
SSHKeyChoiceView, DashboardView)
SSHKeyChoiceView, DashboardView, SettingsView)
urlpatterns = [
url(r'index/?$', IndexView.as_view(), name='index'),
@ -19,6 +20,7 @@ urlpatterns = [
url(r'rails/?$', RailsHostingView.as_view(), name='railshosting'),
url(r'pricing/?$', HostingPricingView.as_view(), name='pricing'),
url(r'payment/?$', PaymentVMView.as_view(), name='payment'),
url(r'settings/?$', SettingsView.as_view(), name='settings'),
url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
url(r'bills/?$', HostingBillListView.as_view(), name='bills'),

View file

@ -196,7 +196,7 @@ class IndexView(View):
class LoginView(LoginViewMixin):
template_name = "hosting/login.html"
form_class = HostingUserLoginForm
success_url = reverse_lazy('hosting:virtual_machines')
success_url = reverse_lazy('hosting:dashboard')
class SignupView(CreateView):
@ -494,6 +494,57 @@ class SSHKeyCreateView(LoginRequiredMixin, FormView):
return self.form_invalid(form)
class SettingsView(LoginRequiredMixin, FormView):
template_name = "hosting/settings.html"
login_url = reverse_lazy('hosting:login')
form_class = BillingAddressForm
def get_form(self, form_class):
"""
Check if the user already saved contact details. If so, then show
the form populated with those details, to let user change them.
"""
return form_class(
instance=self.request.user.billing_addresses.first(),
**self.get_form_kwargs())
def get_context_data(self, **kwargs):
context = super(SettingsView, self).get_context_data(**kwargs)
# Get user
user = self.request.user
# Get user last order
last_hosting_order = HostingOrder.objects.filter(
customer__user=user).last()
# If user has already an hosting order, get the credit card data from
# it
if last_hosting_order:
credit_card_data = last_hosting_order.get_cc_data()
context.update({
'credit_card_data': credit_card_data if credit_card_data else None,
})
context.update({
'stripe_key': settings.STRIPE_API_PUBLIC_KEY
})
return context
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
billing_address_data = form.cleaned_data
billing_address_data.update({
'user': self.request.user.id
})
billing_address_user_form = UserBillingAddressForm(
instance=self.request.user.billing_addresses.first(),
data=billing_address_data)
billing_address_user_form.save()
return self.render_to_response(self.get_context_data())
else:
billing_address_data = form.cleaned_data
return self.form_invalid(form)
class PaymentVMView(LoginRequiredMixin, FormView):
template_name = 'hosting/payment.html'
login_url = reverse_lazy('hosting:login')