Implement login system
Copy over payment system from kumi.xxx Add missing requirements Other stuff
This commit is contained in:
parent
b31ebc4818
commit
54e84be36a
47 changed files with 564 additions and 88 deletions
5
auction/apps.py
Normal file
5
auction/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class AuctionConfig(AppConfig):
|
||||||
|
name = 'auction'
|
16
auction/models.py
Normal file
16
auction/models.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from django.contrib.gis.db import models
|
||||||
|
|
||||||
|
from localauth.models import User
|
||||||
|
|
||||||
|
class Inquiry(models.Model):
|
||||||
|
user = models.ForeignKey(User, models.PROTECT)
|
||||||
|
destination_name = models.CharField(max_length=128)
|
||||||
|
destination_coords = models.PointField()
|
||||||
|
destination_radius = models.IntegerField()
|
||||||
|
budget = models.DecimalField(max_digits=10, decimal_places=2)
|
||||||
|
adults = models.IntegerField()
|
||||||
|
children = models.IntegerField()
|
||||||
|
comment = models.TextField()
|
||||||
|
|
||||||
|
def get_hotels(self):
|
||||||
|
pass
|
10
auction/urls.py
Normal file
10
auction/urls.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from public.views import HomeView
|
||||||
|
|
||||||
|
app_name = "auction"
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('create_inquiry/', HomeView.as_view(), name="create_inquiry"),
|
||||||
|
path('process_inquiry/<slug:uuid>/', HomeView.as_view(), name="process_inquiry"),
|
||||||
|
]
|
|
@ -1,3 +1,4 @@
|
||||||
libpq-dev
|
libpq-dev
|
||||||
build-essential
|
build-essential
|
||||||
libpython3-dev
|
libpython3-dev
|
||||||
|
postgis
|
|
@ -1,5 +0,0 @@
|
||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.admin import UserAdmin
|
|
||||||
from .models import Account
|
|
||||||
|
|
||||||
admin.site.register(Account, UserAdmin)
|
|
12
localauth/forms.py
Normal file
12
localauth/forms.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
|
||||||
|
from .models import User
|
||||||
|
|
||||||
|
class RegistrationForm(UserCreationForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs.pop("request")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ["email", "password1", "password2"]
|
16
localauth/mixins.py
Normal file
16
localauth/mixins.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class SuperUserRequiredMixin(object):
|
||||||
|
"""
|
||||||
|
View mixin which requires that the authenticated user is a super user
|
||||||
|
(i.e. `is_superuser` is True).
|
||||||
|
"""
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
messages.error(
|
||||||
|
request,
|
||||||
|
'You do not have the permission required to perform the '
|
||||||
|
'requested operation.')
|
||||||
|
return redirect(settings.LOGIN_URL)
|
||||||
|
return super(SuperUserRequiredMixin, self).dispatch(request,
|
||||||
|
*args, **kwargs)
|
|
@ -1,58 +1,46 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
||||||
from django.utils import timezone
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.utils import timezone
|
||||||
from polymorphic.models import PolymorphicModel
|
|
||||||
|
|
||||||
class Profile:
|
|
||||||
account = models.ForeignKey(get_user_model(), models.CASCADE)
|
|
||||||
|
|
||||||
class UserManager(BaseUserManager):
|
class UserManager(BaseUserManager):
|
||||||
use_in_migrations = True
|
use_in_migrations = True
|
||||||
|
|
||||||
def _create_user(self, email, password, **extra_fields):
|
def _create_user(self, email, display_name, password, **extra_fields):
|
||||||
now = timezone.now()
|
values = [email, display_name]
|
||||||
if not username:
|
field_value_map = dict(zip(self.model.REQUIRED_FIELDS, values))
|
||||||
raise ValueError('The given username must be set')
|
for field_name, value in field_value_map.items():
|
||||||
|
if not value:
|
||||||
|
raise ValueError('The {} value must be set'.format(field_name))
|
||||||
|
|
||||||
email = self.normalize_email(email)
|
email = self.normalize_email(email)
|
||||||
user = self.model(username=username, email=email,
|
user = self.model(
|
||||||
is_staff=is_staff, is_active=True,
|
email=email,
|
||||||
is_superuser=is_superuser,
|
display_name=display_name,
|
||||||
date_joined=now, **extra_fields)
|
**extra_fields
|
||||||
|
)
|
||||||
user.set_password(password)
|
user.set_password(password)
|
||||||
user.save(using=self._db)
|
user.save(using=self._db)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def create_user(self, username, email=None, password=None, **extra_fields):
|
def create_user(self, email, display_name, password=None, **extra_fields):
|
||||||
return self._create_user(username, email, password, False, False,
|
return self._create_user(email, display_name, password, **extra_fields)
|
||||||
**extra_fields)
|
|
||||||
|
|
||||||
def create_superuser(self, username, email, password, **extra_fields):
|
def create_superuser(self, email, display_name, password=None, **extra_fields):
|
||||||
return self._create_user(username, email, p
|
extra_fields.setdefault('is_superuser', True)
|
||||||
|
return self._create_user(email, display_name, password, **extra_fields)
|
||||||
|
|
||||||
class Account(AbstractBaseUser):
|
class User(AbstractBaseUser):
|
||||||
email = models.EmailField(_('username'), max_length=30, unique=True,
|
email = models.EmailField(unique=True)
|
||||||
help_text=_('Required. 30 characters or fewer. Letters, digits and '
|
is_active = models.BooleanField(default=True)
|
||||||
'@/./+/-/_ only.'),
|
date_joined = models.DateTimeField(default=timezone.now)
|
||||||
validators=[
|
last_login = models.DateTimeField(null=True)
|
||||||
validators.RegexValidator(r'^[\w.@+-]+$',
|
is_superuser = models.BooleanField(default=False)
|
||||||
_('Enter a valid username. '
|
|
||||||
'This value may contain only letters, numbers '
|
|
||||||
'and @/./+/-/_ characters.'), 'invalid'),
|
|
||||||
],
|
|
||||||
error_messages={
|
|
||||||
'unique': _("A user with that username already exists."),
|
|
||||||
})
|
|
||||||
|
|
||||||
objects = AccountManager()
|
objects = UserManager()
|
||||||
|
|
||||||
USERNAME_FIELD = 'email'
|
USERNAME_FIELD = 'email'
|
||||||
REQUIRED_FIELDS = []
|
REQUIRED_FIELDS = ['display_name']
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('account')
|
|
||||||
verbose_name_plural = _('accounts')
|
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
return self.email
|
return self.email
|
||||||
|
@ -60,5 +48,12 @@ class Account(AbstractBaseUser):
|
||||||
def get_short_name(self):
|
def get_short_name(self):
|
||||||
return self.email
|
return self.email
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None, **kwargs):
|
def has_permission(self, *args, **kwargs):
|
||||||
send_mail(subject, message, from_email, [self.email], **kwargs)
|
return self.is_superuser
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_staff(self):
|
||||||
|
return self.is_superuser
|
||||||
|
|
||||||
|
has_module_perms = has_permission
|
||||||
|
has_perm = has_permission
|
11
localauth/urls.py
Normal file
11
localauth/urls.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from .views import LoginView, LogoutView, RegistrationView
|
||||||
|
|
||||||
|
app_name = "localauth"
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('login/', LoginView.as_view(), name="login"),
|
||||||
|
path('logout/', LogoutView.as_view(), name="logout"),
|
||||||
|
path('register/', RegistrationView.as_view(), name="register"),
|
||||||
|
]
|
|
@ -1,3 +1,24 @@
|
||||||
from django.shortcuts import render
|
from django.contrib.auth.views import LoginView as Login, LogoutView as Logout
|
||||||
|
from django.http.response import HttpResponseRedirect
|
||||||
|
from django.contrib.auth import login
|
||||||
|
|
||||||
# Create your views here.
|
from .forms import RegistrationForm
|
||||||
|
from .models import User
|
||||||
|
|
||||||
|
class LoginView(Login):
|
||||||
|
template_name = "localauth/register.html"
|
||||||
|
|
||||||
|
class LogoutView(Logout):
|
||||||
|
next_page = "/"
|
||||||
|
|
||||||
|
class RegistrationView(Login):
|
||||||
|
form_class = RegistrationForm
|
||||||
|
template_name = "localauth/register.html"
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
user = User.objects.create_user(form.cleaned_data["email"], form.cleaned_data["password1"])
|
||||||
|
login(self.request, user)
|
||||||
|
return HttpResponseRedirect(self.get_success_url())
|
||||||
|
|
||||||
|
def get_default_redirect_url(self):
|
||||||
|
return resolve_url(self.next_page or settings.REGISTER_REDIRECT_URL)
|
0
partners/templatetags/__init__.py
Normal file
0
partners/templatetags/__init__.py
Normal file
8
partners/templatetags/offeroptions.py
Normal file
8
partners/templatetags/offeroptions.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def stars(count, color="yellow"):
|
||||||
|
return """
|
||||||
|
"""
|
0
payment/__init__.py
Normal file
0
payment/__init__.py
Normal file
13
payment/admin.py
Normal file
13
payment/admin.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import InvoicePayment, Invoice
|
||||||
|
from .paypal.models import PaypalInvoicePayment
|
||||||
|
from .sepa.models import SepaInvoicePayment
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
|
|
||||||
|
admin.site.register(InvoicePayment)
|
||||||
|
admin.site.register(Invoice)
|
||||||
|
|
||||||
|
admin.site.register(PaypalInvoicePayment)
|
||||||
|
admin.site.register(SepaInvoicePayment)
|
5
payment/apps.py
Normal file
5
payment/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentConfig(AppConfig):
|
||||||
|
name = 'payment'
|
4
payment/functions.py
Normal file
4
payment/functions.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
def invoice_upload_path(instance, filename):
|
||||||
|
return "/".join(["userfiles", str(instance.user.id), str(uuid.uuid4()), filename])
|
134
payment/models.py
Normal file
134
payment/models.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
|
from pyinvoice.models import InvoiceInfo, ServiceProviderInfo, ClientInfo, Item, Transaction, PDFInfo
|
||||||
|
from pyinvoice.templates import SimpleInvoice
|
||||||
|
|
||||||
|
from polymorphic.models import PolymorphicModel
|
||||||
|
from django_countries.fields import CountryField
|
||||||
|
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
from dbsettings.functions import getValue
|
||||||
|
|
||||||
|
from .functions import invoice_upload_path
|
||||||
|
|
||||||
|
class BillingAddress(models.Model):
|
||||||
|
user = models.ForeignKey(get_user_model(), models.CASCADE)
|
||||||
|
first_name = models.CharField(max_length=64)
|
||||||
|
last_name = models.CharField(max_length=64)
|
||||||
|
street = models.CharField(max_length=128)
|
||||||
|
city = models.CharField(max_length=64)
|
||||||
|
zip = models.CharField(max_length=16)
|
||||||
|
state = models.CharField(max_length=32, null=True, blank=True)
|
||||||
|
country = CountryField()
|
||||||
|
|
||||||
|
class Invoice(models.Model):
|
||||||
|
user = models.ForeignKey(get_user_model(), models.PROTECT)
|
||||||
|
billing_address = models.ForeignKey(BillingAddress, models.PROTECT)
|
||||||
|
currency = models.CharField(max_length=3)
|
||||||
|
tax_rate = models.DecimalField(max_digits=4, decimal_places=2)
|
||||||
|
invoice = models.FileField(null=True, blank=True, upload_to=invoice_upload_path)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def price_net(self):
|
||||||
|
price = 0
|
||||||
|
|
||||||
|
for item in self.invoiceitem_set().all():
|
||||||
|
price += item.net_total
|
||||||
|
|
||||||
|
return price
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tax(self):
|
||||||
|
return round(self.price_net * self.tax_rate / 100, 2)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def price_gross(self):
|
||||||
|
return self.price_net + self.tax
|
||||||
|
|
||||||
|
@property
|
||||||
|
def payment_instructions(self):
|
||||||
|
return "Alle Preise in %s." % self.currency
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def generate_invoice(self):
|
||||||
|
output = BytesIO()
|
||||||
|
|
||||||
|
pdfinfo = PDFInfo(title='Rechnung', author='Kumi Media Ltd.', subject='Rechnung')
|
||||||
|
doc = SimpleInvoice(output, pdfinfo)
|
||||||
|
|
||||||
|
doc.is_paid = True
|
||||||
|
|
||||||
|
doc.invoice_info = InvoiceInfo("%s%i" % (getValue("billing.prefix", ""), self.id), timezone.now().date(), timezone.now().date())
|
||||||
|
|
||||||
|
provider_data = { key: value for key, value in {
|
||||||
|
"name": getValue("billing.provider.name", False),
|
||||||
|
"street": getValue("billing.provider.street", False),
|
||||||
|
"city": getValue("billing.provider.city", False),
|
||||||
|
"state": getValue("billing.provider.state", False),
|
||||||
|
"country": getValue("billing.provider.country", False),
|
||||||
|
"post_code": getValue("billing.provider.zip", False),
|
||||||
|
"vat_tax_number": getValue("billing.provider.vat_id", False)
|
||||||
|
}.items() if value}
|
||||||
|
|
||||||
|
doc.service_provider_info = ServiceProviderInfo(**provider_data)
|
||||||
|
|
||||||
|
logo_url = getValue("billing.logo_url", False)
|
||||||
|
if logo_url:
|
||||||
|
try:
|
||||||
|
logo = BytesIO(urllib.request.urlopen(logo_url).read())
|
||||||
|
doc.logo(logo)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
doc.client_info = ClientInfo(email='invoice.user.email', country="Austria")
|
||||||
|
|
||||||
|
for item in self.invoiceitem_set().all():
|
||||||
|
doc.add_item(Item(item.name, item.description, item.count, item.net_each))
|
||||||
|
|
||||||
|
doc.set_item_tax_rate(self.tax_rate)
|
||||||
|
|
||||||
|
for payment in self.invoicepayment_set().all():
|
||||||
|
doc.add_transaction(Transaction(payment.gateway, payment.gateway_id, payment.timestamp, payment.amount))
|
||||||
|
|
||||||
|
bottom_tip = (f"{ self.payment_instructions }<br /><br />" if self.payment_instructions else "") + getValue("billing.bottom_tip", "")
|
||||||
|
bottom_tip += "<br /><br />" if bottom_tip else ""
|
||||||
|
bottom_tip += "Rechnung erstellt: %s" % str(timezone.now())
|
||||||
|
|
||||||
|
doc.set_bottom_tip(bottom_tip)
|
||||||
|
|
||||||
|
doc.finish()
|
||||||
|
|
||||||
|
self.invoice = ContentFile(output.getvalue(), "invoice.pdf")
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
class InvoiceItem(models.Model):
|
||||||
|
invoice = models.ForeignKey(Invoice, models.CASCADE)
|
||||||
|
name = models.CharField(max_length=64)
|
||||||
|
description = models.CharField(max_length=256, null=True, blank=True)
|
||||||
|
count = models.IntegerField()
|
||||||
|
net_each = models.DecimalField(max_digits=11, decimal_places=2)
|
||||||
|
|
||||||
|
class InvoicePayment(PolymorphicModel):
|
||||||
|
invoice = models.ForeignKey(Invoice, models.PROTECT)
|
||||||
|
amount = models.DecimalField(max_digits=9, decimal_places=2)
|
||||||
|
gateway_id = models.CharField(max_length=256)
|
||||||
|
timestamp = models.DateTimeField(default=timezone.now)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gateway(self):
|
||||||
|
raise NotImplementedError("%s does not implement gateway" % type(self))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def initiate(invoice):
|
||||||
|
raise NotImplementedError("%s does not implement initiate()" % type(self))
|
0
payment/paypal/__init__.py
Normal file
0
payment/paypal/__init__.py
Normal file
9
payment/paypal/api.py
Normal file
9
payment/paypal/api.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment, LiveEnvironment
|
||||||
|
|
||||||
|
from dbsettings.functions import getValue
|
||||||
|
|
||||||
|
class PaypalAPI:
|
||||||
|
def __init__(self, client_id=None, client_secret=None, mode=None):
|
||||||
|
mode = SandboxEnvironment if (client_secret == "sandbox" or getValue("paypal.mode") == "sandbox") else LiveEnvironment
|
||||||
|
environment = mode(client_id=(client_id or getValue("paypal.client_id")), client_secret=(client_secret or getValue("paypal.client_secret")))
|
||||||
|
self.client = PayPalHttpClient(environment)
|
64
payment/paypal/models.py
Normal file
64
payment/paypal/models.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
from payment.models import InvoicePayment, Invoice
|
||||||
|
|
||||||
|
from .api import PaypalAPI
|
||||||
|
|
||||||
|
from paypalcheckoutsdk.orders import OrdersCreateRequest
|
||||||
|
from paypalhttp import HttpError
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
from dbsettings.functions import getValue
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class PaypalOrder(models.Model):
|
||||||
|
invoice = models.ForeignKey(Invoice, models.CASCADE)
|
||||||
|
order_id = models.CharField(max_length=64)
|
||||||
|
|
||||||
|
class PaypalInvoicePayment(InvoicePayment):
|
||||||
|
@property
|
||||||
|
def gateway(self):
|
||||||
|
return "Paypal"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def initiate(invoice):
|
||||||
|
request = OrdersCreateRequest()
|
||||||
|
request.prefer('return=representation')
|
||||||
|
|
||||||
|
request.request_body (
|
||||||
|
{
|
||||||
|
"intent": "CAPTURE",
|
||||||
|
"purchase_units": [
|
||||||
|
{
|
||||||
|
"amount": {
|
||||||
|
"currency_code": invoice.currency,
|
||||||
|
"value": float(invoice.price_gross)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"application_context": {
|
||||||
|
"return_url": getValue("application.base_url") + reverse_lazy("this_sucks"),
|
||||||
|
"cancel_url": getValue("application.base_url"),
|
||||||
|
"brand_name": getValue("application.name", "JourneyJoker"),
|
||||||
|
"landing_page": "BILLING",
|
||||||
|
"user_action": "CONTINUE"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = PaypalAPI().client
|
||||||
|
response = client.execute(request)
|
||||||
|
PaypalOrder.objects.create(subscription=subscription, order_id=response.result.id)
|
||||||
|
|
||||||
|
for link in response.result.links:
|
||||||
|
if link.rel == "approve":
|
||||||
|
return link.href
|
||||||
|
|
||||||
|
except IOError as ioe:
|
||||||
|
logger.error(ioe)
|
||||||
|
if isinstance(ioe, HttpError):
|
||||||
|
logger.error(ioe.status_code)
|
4
payment/paypal/urls.py
Normal file
4
payment/paypal/urls.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
]
|
0
payment/sepa/__init__.py
Normal file
0
payment/sepa/__init__.py
Normal file
5
payment/sepa/forms.py
Normal file
5
payment/sepa/forms.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
class SepaApplyPaymentForm(forms.Form):
|
||||||
|
reference = forms.CharField()
|
||||||
|
amount = forms.DecimalField(max_digits=11, decimal_places=2)
|
59
payment/sepa/functions.py
Normal file
59
payment/sepa/functions.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import string
|
||||||
|
import re
|
||||||
|
import random
|
||||||
|
|
||||||
|
from dbsettings.functions import getValue
|
||||||
|
|
||||||
|
import qrcode
|
||||||
|
|
||||||
|
QRCODE_CONTENT = """
|
||||||
|
BCD
|
||||||
|
002
|
||||||
|
1
|
||||||
|
SCT
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
def generate_rf(reference):
|
||||||
|
reference = str(reference).upper().zfill(21) + "RF00"
|
||||||
|
pattern = re.compile("[A-Z0-9]+")
|
||||||
|
if not pattern.fullmatch(reference):
|
||||||
|
raise ValueError("Not a valid reference: %s – may only contain 0-9 and A-Z!")
|
||||||
|
|
||||||
|
code = ""
|
||||||
|
|
||||||
|
chars = string.digits + string.ascii_uppercase
|
||||||
|
|
||||||
|
for char in reference:
|
||||||
|
code += str(chars.index(char))
|
||||||
|
|
||||||
|
remainder = int(code) % 97
|
||||||
|
|
||||||
|
checksum = 98 - remainder
|
||||||
|
|
||||||
|
return "RF%i%s" % (checksum, reference[:-4])
|
||||||
|
|
||||||
|
def generate_reference(length=21):
|
||||||
|
return "".join([random.SystemRandom().choice(string.digits + string.ascii_uppercase) for i in range(length)])
|
||||||
|
|
||||||
|
def generate_qrcode(amount, iban="", recipient="", bic="", reference="", currency="EUR", message="", purpose="", notice=""):
|
||||||
|
content = QRCODE_CONTENT % (
|
||||||
|
bic or getValue("sepa.bic", ""),
|
||||||
|
recipient or getValue("sepa.account_holder", ""),
|
||||||
|
iban or getValue("sepa.iban"),
|
||||||
|
currency,
|
||||||
|
"{:0.2f}".format(float(amount)).rstrip("0"),
|
||||||
|
purpose,
|
||||||
|
reference if (not reference) or str(reference).startswith("RF") or len(str(reference)) > 21 else generate_rf(reference),
|
||||||
|
message,
|
||||||
|
notice
|
||||||
|
)
|
||||||
|
|
||||||
|
return qrcode.make(content)
|
21
payment/sepa/models.py
Normal file
21
payment/sepa/models.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from payment.models import InvoicePayment, Invoice
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
|
from .functions import generate_reference
|
||||||
|
|
||||||
|
class SepaPaymentReference(models.Model):
|
||||||
|
invoice = models.ForeignKey(Invoice, models.CASCADE)
|
||||||
|
reference = models.IntegerField(default=generate_reference)
|
||||||
|
|
||||||
|
class SepaInvoicePayment(InvoicePayment):
|
||||||
|
@property
|
||||||
|
def gateway(self):
|
||||||
|
return "Bank Transfer"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def initiate(subscription):
|
||||||
|
SepaPaymentReference.objects.get_or_create(subscription=subscription)
|
4
payment/sepa/urls.py
Normal file
4
payment/sepa/urls.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
]
|
23
payment/sepa/views.py
Normal file
23
payment/sepa/views.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
from django.views.generic import FormView
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
|
from localauth.mixins import SuperUserRequiredMixin
|
||||||
|
|
||||||
|
from .forms import SepaApplyPaymentForm
|
||||||
|
from .models import SepaPaymentReference, SepaInvoicePayment
|
||||||
|
|
||||||
|
class SepaApplyPaymentView(SuperUserRequiredMixin, FormView):
|
||||||
|
form_class = SepaApplyPaymentForm
|
||||||
|
success_url = '/'
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
reference = form.cleaned_data["reference"]
|
||||||
|
pr = get_object_or_404(SepaPaymentReference, reference=reference)
|
||||||
|
invoice = pr.invoice
|
||||||
|
|
||||||
|
SepaInvoicePayment.objects.create(invoice=invoice, amount=form.cleaned_data["amount"])
|
||||||
|
|
||||||
|
messages.success(self.request, "Zahlung angewendet.")
|
||||||
|
|
||||||
|
return super().form_valid(form)
|
3
payment/tests.py
Normal file
3
payment/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
6
payment/urls.py
Normal file
6
payment/urls.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('gateways/paypal/', include("payment.paypal.urls")),
|
||||||
|
path('gateways/sepa/', include("payment.sepa.urls")),
|
||||||
|
]
|
0
payment/views.py
Normal file
0
payment/views.py
Normal file
|
@ -1,5 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class PaymentsConfig(AppConfig):
|
|
||||||
name = 'payments'
|
|
|
@ -1,3 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
# Create your models here.
|
|
0
public/templatetags/__init__.py
Normal file
0
public/templatetags/__init__.py
Normal file
8
public/templatetags/testimonials.py
Normal file
8
public/templatetags/testimonials.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def testimonials():
|
||||||
|
return """
|
||||||
|
"""
|
9
public/urls.py
Normal file
9
public/urls.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from .views import HomeView
|
||||||
|
|
||||||
|
app_name = "frontend"
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', HomeView.as_view(), name="home"),
|
||||||
|
]
|
|
@ -1,3 +1,4 @@
|
||||||
from django.shortcuts import render
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
# Create your views here.
|
class HomeView(TemplateView):
|
||||||
|
template_name = "frontend/index.html"
|
|
@ -1,3 +1,8 @@
|
||||||
Django
|
Django
|
||||||
django-polymorphic
|
django-polymorphic
|
||||||
psycopg2
|
psycopg2
|
||||||
|
dbsettings
|
||||||
|
django-bootstrap4
|
||||||
|
pyinvoice
|
||||||
|
django-countries
|
||||||
|
paypal-checkout-serversdk
|
|
@ -4,7 +4,7 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Urlaubsauktion - {{ title }}</title>
|
<title>JourneyJoker{% if title %} - {{ title }}{% endif %}</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
|
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
|
||||||
|
@ -84,11 +84,11 @@
|
||||||
<div id="links">
|
<div id="links">
|
||||||
<ul class="list-unstyled list-inline">
|
<ul class="list-unstyled list-inline">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.username }}</li>
|
<li class="list-inline-item">{% trans "Eingeloggt als:" %} {{ request.user.email }} | </li>
|
||||||
<li class="list-inline-item"><a href="{% url "profiles:logout" %}"><span><i class="fa fa-lock"></i></span>{% trans "Logout" %}</a></li>
|
<li class="list-inline-item"><a href="{% url "localauth:logout" %}"><span><i class="fa fa-lock"></i></span>{% trans "Logout" %}</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="list-inline-item"><a href="{% url "profiles:login" %}?next={{ request.path }}"><span><i class="fa fa-lock"></i></span>{% trans "Login" %}</a></li>
|
<li class="list-inline-item"><a href="{% url "localauth:login" %}?next={{ request.path }}"><span><i class="fa fa-lock"></i></span>{% trans "Login" %}</a></li>
|
||||||
<li class="list-inline-item"><a href="{% url "profiles:register" %}?next={{ request.path }}"><span><i class="fa fa-plus"></i></span>{% trans "Registrieren" %}</a></li>
|
<li class="list-inline-item"><a href="{% url "localauth:register" %}?next={{ request.path }}"><span><i class="fa fa-plus"></i></span>{% trans "Registrieren" %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="list-inline-item">
|
<li class="list-inline-item">
|
||||||
<form>
|
<form>
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
<nav class="navbar navbar-expand-xl sticky-top navbar-custom main-navbar p-1" id="mynavbar-1">
|
<nav class="navbar navbar-expand-xl sticky-top navbar-custom main-navbar p-1" id="mynavbar-1">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<a href="{% url "frontend:index" %}" class="navbar-brand py-1 m-0"><span><i class="fa fa-plane"></i>URLAUBS</span>AUKTION</a>
|
<a href="{% url "frontend:home" %}" class="navbar-brand py-1 m-0"><span><i class="fa fa-plane"></i>JOURNEY</span>JOKER</a>
|
||||||
<div class="header-search d-xl-none my-auto ml-auto py-1">
|
<div class="header-search d-xl-none my-auto ml-auto py-1">
|
||||||
<a href="#" class="search-button" onClick="openSearch()"><span><i class="fa fa-search"></i></span></a>
|
<a href="#" class="search-button" onClick="openSearch()"><span><i class="fa fa-search"></i></span></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -139,30 +139,28 @@
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a href="/" class="nav-link" id="navbarDropdown" role="button">{% trans "Home" %}</a>
|
<a href="/" class="nav-link" id="navbarDropdown" role="button">{% trans "Home" %}</a>
|
||||||
</li>
|
</li>
|
||||||
{% if request.user.clientprofile or not request.user.partnerprofile %}
|
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a href="#" class="nav-link" data-toggle="dropdown">{% trans "Meine Urlaubsauktion" %}<span><i class="fa fa-angle-down"></i></span></a>
|
<a href="#" class="nav-link" data-toggle="dropdown">{% trans "Mein Urlaub" %}<span><i class="fa fa-angle-down"></i></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li><a class="dropdown-item" href="/">{% trans "Gestellte Anfragen" %}</a></li>
|
<li><a class="dropdown-item" href="/">{% trans "Gestellte Anfragen" %}</a></li>
|
||||||
<li><a class="dropdown-item" href="/">{% trans "Gebuchte Reisen" %}</a></li>
|
<li><a class="dropdown-item" href="/">{% trans "Gebuchte Reisen" %}</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a class="dropdown-item" href="{% url "profiles:login" %}?next={{ request.path }}">{% trans "Login" %}</a></li>
|
<li><a class="dropdown-item" href="{% url "localauth:login" %}?next={{ request.path }}">{% trans "Login" %}</a></li>
|
||||||
<li><a class="dropdown-item" href="{% url "profiles:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li>
|
<li><a class="dropdown-item" href="{% url "localauth:register" %}?next={{ request.path }}">{% trans "Registrieren" %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
|
||||||
{% if request.user.partnerprofile %}
|
{% if request.user.partnerprofile %}
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a href="#" class="nav-link" data-toggle="dropdown">B2B<span><i class="fa fa-angle-down"></i></span></a>
|
<a href="#" class="nav-link" data-toggle="dropdown">B2B<span><i class="fa fa-angle-down"></i></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
{% if not request.user.partnerprofile %}
|
{% if not request.user.partnerprofile %}
|
||||||
<li><a class="dropdown-item" href="/">{% trans "Als Anbieter anmelden" %}</a></li>
|
<li><a class="dropdown-item" href="/">{% trans "Als Anbieter anmelden" %}</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a class="dropdown-item" href="/">{% trans "Bieten" %}</a></li>
|
<li><a class="dropdown-item" href="/">{% trans "Bieten" %}</a></li>
|
||||||
<li><a class="dropdown-item" href="/">{% trans "Buchungen verwalten" %}</a></li>
|
<li><a class="dropdown-item" href="/">{% trans "Buchungen verwalten" %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -452,7 +450,7 @@
|
||||||
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-contact">
|
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-contact">
|
||||||
<h3 class="footer-heading">Kontakt</h3>
|
<h3 class="footer-heading">Kontakt</h3>
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li><span><i class="fa fa-map-marker"></i></span>Think:Put – Die Agentur für Denken & Tun, Kolingasse 10/10, 1090 Wien</li>
|
<li><span><i class="fa fa-map-marker"></i></span>Think:Put<br>Die Agentur für Denken & Tun<br>Kolingasse 10/10<br>1090 Wien</li>
|
||||||
<!--<li><span><i class="fa fa-phone"></i></span>+43 800 093004</li>
|
<!--<li><span><i class="fa fa-phone"></i></span>+43 800 093004</li>
|
||||||
<li><span><i class="fa fa-envelope"></i></span>office@kumi.systems</li>-->
|
<li><span><i class="fa fa-envelope"></i></span>office@kumi.systems</li>-->
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -466,7 +464,7 @@
|
||||||
</div><!-- end columns -->
|
</div><!-- end columns -->
|
||||||
|
|
||||||
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-links ftr-pad-left">
|
<div class="col-12 col-md-6 col-lg-3 col-xl-3 footer-widget ftr-links ftr-pad-left">
|
||||||
<h3 class="footer-heading">Urlaubsauktion</h3>
|
<h3 class="footer-heading">JourneyJoker</h3>
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li><a href="#">Impressum</a></li>
|
<li><a href="#">Impressum</a></li>
|
||||||
<li><a href="#">Kontakt</a></li>
|
<li><a href="#">Kontakt</a></li>
|
||||||
|
@ -477,7 +475,7 @@
|
||||||
|
|
||||||
<div class="col-12 col-md-6 col-lg-4 col-xl-4 footer-widget ftr-about">
|
<div class="col-12 col-md-6 col-lg-4 col-xl-4 footer-widget ftr-about">
|
||||||
<h3 class="footer-heading">Über uns</h3>
|
<h3 class="footer-heading">Über uns</h3>
|
||||||
<p>Die Urlaubsauktion ist ur leiwand. Oida.</p>
|
<p>Der Joker ist ur leiwand. Oida.</p>
|
||||||
<ul class="social-links list-inline list-unstyled">
|
<ul class="social-links list-inline list-unstyled">
|
||||||
<li class="list-inline-item"><a href="#"><span><i class="fab fa-facebook"></i></span></a></li>
|
<li class="list-inline-item"><a href="#"><span><i class="fab fa-facebook"></i></span></a></li>
|
||||||
<li class="list-inline-item"><a href="#"><span><i class="fab fa-twitter"></i></span></a></li>
|
<li class="list-inline-item"><a href="#"><span><i class="fab fa-twitter"></i></span></a></li>
|
||||||
|
@ -497,7 +495,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="copyright">
|
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="copyright">
|
||||||
<p>© 2020 <a href="https://thinkput.at/">Think:Put – Die Agentur für Denken & Tun</a> – Web-Entwicklung: <a href="https://">Kumi Systems e.U.</a></p>
|
<p>© 2020 – 2021 <a href="https://thinkput.at/">Think:Put – Die Agentur für Denken & Tun</a></p><p>Entwicklung: <a href="https://kumi.systems/">Kumi Systems e.U.</a> – <a href="https://kumi.media">Kumi Media Ltd.</a></p>
|
||||||
</div><!-- end columns -->
|
</div><!-- end columns -->
|
||||||
|
|
||||||
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="terms">
|
<div class="col-12 col-md-6 col-lg-6 col-xl-6" id="terms">
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
height:100%;">
|
height:100%;">
|
||||||
<div class=" meta">
|
<div class=" meta">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{% trans "Willkommen zur großen" %}</h2>
|
<h2>{% trans "Willkommen bei JourneyJoker" %}</h2>
|
||||||
<h1>{% trans "Urlaubs-Umkehrauktion" %}</h1>
|
<h1>{% trans "Mein Urlaub nach Maß" %}</h1>
|
||||||
<a href="#" class="btn btn-default">{% trans "Was bedeutet das?" %}</a>
|
<a href="#" class="btn btn-default">{% trans "Wie geht das?" %}</a>
|
||||||
</div><!-- end container -->
|
</div><!-- end container -->
|
||||||
</div><!-- end meta -->
|
</div><!-- end meta -->
|
||||||
</li><!-- end item-1 -->
|
</li><!-- end item-1 -->
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap4 %}
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Urlaubsauktion - {{ title }}</title>
|
<title>JourneyJoker - {{ title }}</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
|
<link rel="icon" href="{% static "frontend/images/favicon.png" %}" type="image/x-icon">
|
||||||
|
@ -44,14 +44,14 @@
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
|
||||||
<div class="full-page-title">
|
<div class="full-page-title">
|
||||||
<a href="{% url "frontend:index" %}"><h3 class="company-name"><span><i class="fa fa-plane"></i>Urlaubs</span>Auktion</h3></a>
|
<a href="{% url "frontend:home" %}"><h3 class="company-name"><span><i class="fa fa-plane"></i>Journey</span>Joker</h3></a>
|
||||||
</div><!-- end full-page-title -->
|
</div><!-- end full-page-title -->
|
||||||
|
|
||||||
<div class="custom-form custom-form-fields">
|
<div class="custom-form custom-form-fields">
|
||||||
<h3>{{ title }}</h3>
|
<h3>{{ title }}</h3>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|bootstrap }}
|
{% bootstrap_form form %}
|
||||||
<button class="btn btn-orange btn-block">{% trans "Login" %}</button>
|
<button class="btn btn-orange btn-block">{% trans "Login" %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
</div><!-- end other-links -->
|
</div><!-- end other-links -->
|
||||||
</div><!-- end custom-form -->
|
</div><!-- end custom-form -->
|
||||||
|
|
||||||
<p class="full-page-copyright">© 2020 <a href="https://kumi.systems/">Kumi Systems e.U.</a> All rights reserved.</p>
|
<p class="full-page-copyright">© 2020 – 2021 <a href="https://kumi.systems/">Kumi Systems e.U.</a> All rights reserved.</p>
|
||||||
</div><!-- end columns -->
|
</div><!-- end columns -->
|
||||||
</div><!-- end row -->
|
</div><!-- end row -->
|
||||||
</div><!-- end container -->
|
</div><!-- end container -->
|
|
@ -15,6 +15,14 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'localauth',
|
'localauth',
|
||||||
|
'public',
|
||||||
|
'partners',
|
||||||
|
'payment',
|
||||||
|
'clients',
|
||||||
|
'dbsettings',
|
||||||
|
'auction',
|
||||||
|
'bootstrap4',
|
||||||
|
'django_countries',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
@ -32,7 +40,7 @@ ROOT_URLCONF = 'urlaubsauktion.urls'
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': [],
|
'DIRS': [BASE_DIR / "templates"],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
|
@ -53,7 +61,7 @@ WSGI_APPLICATION = 'urlaubsauktion.wsgi.application'
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
'ENGINE': 'django.contrib.gis.db.backends.postgis',
|
||||||
'NAME': DB_NAME,
|
'NAME': DB_NAME,
|
||||||
'USER': DB_USER,
|
'USER': DB_USER,
|
||||||
'PASSWORD': DB_PASS,
|
'PASSWORD': DB_PASS,
|
||||||
|
@ -101,4 +109,11 @@ USE_TZ = True
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
AUTH_USER_MODEL = "localauth.Account"
|
STATICFILES_DIRS = [
|
||||||
|
BASE_DIR / "static",
|
||||||
|
]
|
||||||
|
|
||||||
|
AUTH_USER_MODEL = "localauth.User"
|
||||||
|
|
||||||
|
REGISTER_REDIRECT_URL = "/"
|
||||||
|
LOGIN_REDIRECT_URL = "/"
|
|
@ -14,8 +14,12 @@ Including another URLconf
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('public.urls')),
|
||||||
|
path('auth/', include('localauth.urls')),
|
||||||
|
path('auction/', include('auction.urls')),
|
||||||
|
path('payment/', include('payment.urls')),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue