Django Post Deployment Issues - Scripts and Models

183 Views Asked by At

Hi it's my first time deploying a Django app. I'm using PythonAnywhere to host and learn more. I am aware that deployment requires additional steps and code changes versus dev and believe I have taken these steps researching the documentation and other issues on Stack Overflow.

After separating out javascript from the html, migrating the models and collecting the static files I'm having a major issue with the style of the index file not inheriting the base layout as well as being running the javascript. Additionally drop downfields that are reading from models are not working.

Note all other pages are inheriting the base file but are not linking to models either for dropdowns. I've reviewed the models and they are in place and populated. Likely I am missing something with the base layout file and the models.

Greatly appreciate if someone can point me in the right direction.

Layout.html (base layout file)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/bootstrap.min.css' %}" />
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/site.css' %}" />
    <script src="{% static 'app/scripts/modernizr-2.6.2.js' %}"></script>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" />

</head>

<body>
    <nav class="navbar navbar-dark bg-primary">
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                     <a class="navbar-brand" href="/"> <img id="logo" align ="top" alt="ShowVroom" height ="30" width = "100" src = "data:image/png;base64, ........" /></a>
                </div>

                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav" align="middle">
                        <!--<li><a href="{% url 'home' %}">Home</a></li>-->
                        <li><a href="{% url 'register' %}">Register</a></li>
                        <li><a href="{% url 'about' %}">About</a></li>
                        <li><a href="{% url 'contact' %}">Contact</a></li>
                    </ul>
                    {% include 'app/loginpartial.html' %}
                </div>
            </div>
        </div>
    </nav>


    <div class="container body-content">
{% block content %}{% endblock %}

        <footer>
            <center>
                <p>
                    <a href="{% url 'dealer_reg' %}">Dealer Registration</a>
                </p>

                <p>
                    <a href="{% url 'garageinput' %}">Dealer Dashboard</a>
                </p>

                <p>
                    <a href="{% url 'terms' %}">Terms and Conditions</a>
                </p>
                <p>
                    <a href="{% url 'privacy' %}">Privacy Statement</a>
                </p>
                <p>
                    <a href="/"> <img id="logo" align ="middle" alt="ShowVroom" height ="60" width = "90" src = "data:image/png;base64, ........"/>
                </p>

                <p>
                    All Rights Reserved: AM Group Ltd
                </p>
            </center>
        </footer>


    </div>
 {% block scripts %}
    <script src="{% static 'app/scripts/jquery-1.10.2.js' %}"></script>
    <script src="{% static 'app/scripts/bootstrap.js' %}"></script>
    <script src="{% static 'app/scripts/respond.js' %}"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" />

{% endblock %}

{% block extrascripts %}
<script type="text/JavaScript" src="{%  static 'Index_dependency.js' %}"></script>
<script type="text/JavaScript" src="{%  static 'index_search_drop_downs.js' %}"></script>

{% endblock %}

</body>
</html>

Index.html (Contains 3 dropdowns populated from Models, Car model and make are chained via JavaScript)

<html>

{% load static %}
<head>

</head>


{% extends "layout.html" %}

{% block content %}

<body>
<div class="container">
    <div class="jumbotron" style="background-image: url(https://t4.ftcdn.net/jpg/02/59/17/83/240_F_259178343_D9wu1JKg49PF0nywVuY7K27I0bMgt7hx.jpg); background-size: 100% 110%;">

        <h3 style ="color:midnightblue; text-align:left; font-family:verdana">
            Take the hassle ...
            <br>
                out of the haggle ...
            </br>
        </h3>

        <p color:white;"></p>
    </div>
</div>


<div class="row">
    <div class="col-md-4">
        <h2>Browse the Showroom</h2>
            <p>Choose a make, model and a county to get started</p>
            {#<! -- Drop Downs  -->#}
            <form  action = "{% url 'search_results'%}" enctype="multipart/form-data" method="get">
                <label for="makeddl">Choose Make</label>
                    {<select id="makeddl" name="makeselection">
                        <option  disabled selected="true">Choose Make</option>
                        {% for makes in MotorMakesView %}
                        <option value ="{{ makes.MotorMakeName}}"> {{ makes.MotorMakeName }} </option>
                        {% endfor %}
                    </select>
                <br><br>

                <label for="modelddl">Choose Model</label>
                    <select id="modelddl" name="modelselection">
                        <option disabled selected ="True">\Choose Model</option>
                        {% for mods in MotorModelsView %}
                        <option value= "{{ mods.MotorMakeName}}"> {{ mods.MotorModelName}} </option>
                        {% endfor %}
                    </select>}
                <br><br>

                <label for="countyddl">Choose County</label>
                    <select type>
                        <option>County</option>
                        {% for result in County %}
                        <option>{{result.CountyName}}</option>
                        {% endfor %}
                    </select>
                <br><br>

                <input type="hidden" name="modelval" value=""/>
             {#<! -- Submit Button -->#}
                <input type="submit" class="btn btn-default" value="Search &raquo" &raquo; />
                {% csrf_token %}
            </form>

    </div>

    <div class="col-md-4">
        <h2>Estimate Trade-in Value</h2>
        <p>Estimate the trade in value fo your car before speaking with the dealer.</p>
        <p><a class="btn btn-default" href="https://www.myvehicle.ie/faq/can-you-tell-me-what-the-true-value-of-the-car-is/">Learn more &raquo;</a></p>
    </div>
    <div class="col-md-4">
        <h2>Arrange a Loan</h2>
        <p>Apply for a loan with our partner ....</p>
        <p><a class="btn btn-default" href="https://carloans4u.ie/?gclid=CjwKCAjw57b3BRBlEiwA1ImytlZI9xjld1wY7n1ln6gERfjTCtwyXoBzj_6p-41pq7UxgDkY16ChVRoC2TUQAvD_BwE">Learn more &raquo;</a></p>
    </div>
</div>

</body>


{% block extrascripts %}
    <script>
        var $makevar = $("#makeddl");
            $modelvar = $("#modelddl");
            $options = $modelvar.find('option');
    </script>
    <script type="text/JavaScript" src="{%  static 'index_search_drop_downs.js' %}"></script>


     <script>
        var $modelval
    </script>
    <script type="text/JavaScript" src="{%  static 'Index_dependency.js' %}"></script>

{% endblock %}

{% endblock %}

</html>

index_populate_dropdowns

<script>
            $(document).ready(function()
            {
                    var $makevar = $("#makeddl");
                        $modelvar = $("#modelddl");
                        $options = $modelvar.find('option');
                        $makevar.on('change',function()
                        {
                        $modelvar.html($options.filter('[value="' + this.value + '"]'));
                        }).trigger('change');

            });
        </script>

index_dependency.js #potentially should just have the 2 javascripts files as one, this one updates the make based on the model value

 <script type="text/javascript">
            function getOption() {
                selectElement =  document.querySelector('#modelddl');
                var $modelval = selectElement.value;

            };
        </script>

Views.py Note the index file is called home in this project

Definition of views.
"""
from django.contrib.auth import login, authenticate
#from django.contrib.auth.forms import UserCreationForm

from tablib import Dataset
from datetime import datetime
from django.shortcuts import render
from django.http import HttpRequest
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template
from django.template import Context
from django.utils.encoding import force_text
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.sites.shortcuts import get_current_site
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.template.loader import render_to_string
from DjangoProtoV2.token import account_activation_token
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from django.http import HttpResponseRedirect
import json as simplejson
from django.db.models import Q
from django.core.mail import EmailMessage


#SendGrid Email
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from django.conf import settings
#os
import os


#forms
from .forms import GarageCarForm
from .forms import SignUpForm, MotorSearchForm
from .forms import GarageProfileForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import UserCreationForm

#models
#from .models import CarListing1
from .models import County, MotorMakes, MotorModelsV2, MotorDetail
from .models import GarageInventory
from .models import GarageProfile
from .models import User


def home(request): #this is the index file
    """Renders the home page."""
    #inputvalue=request.GET.get('modelddl',False) # get the model value to pass to search results
    displayCounty=County.objects.all()
    displayMake=MotorMakes.objects.all()
    displayModel=MotorModelsV2.objects.all()
    #displayDetail=MotorDetail.objects.all()
    return render(request, 'index.html',{'County':displayCounty, 'MotorMakesView':displayMake, 'MotorModelsView':displayModel})# 'MotorDetailView':displayDetail})


    #return render(request, 'index', {'ListModels': ListModels})
    #return render(request, 'index.html',)

    assert isinstance(request, HttpRequest)
    return render(
        request,
        'app/index.html',
        {
            'title':'Home Page',
            'year':datetime.now().year,
        }


def SearchInventory(request):
    if request.method=='GET':
        inputvalue = request.GET['modelselection']
        print(inputvalue)
        displayInventory = GarageInventory.objects.all().filter(ListModel=inputvalue)
    else:
        displayInventory = GarageInventory.objects.all()

    return render(request, 'search_results.html', {'GarageInventoryView':displayInventory}


def dealer_reg(request):
    """Renders the about page."""
    assert isinstance(request, HttpRequest)
    return render(
        request,
        'app/dealer_reg.html',
        {
            'title':'About',
            'message':'Your application description page.',
            'year':datetime.now().year,
        }
    )

################ login forms###################################################
def Login(request):
    if request.method == 'POST':

        # AuthenticationForm_can_also_be_used__

        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username = username, password = password)
        if user is not None:
            form = login(request, user)
            messages.success(request, f' wecome {username} !!')
            return redirect('home')
        else:
            messages.info(request, f'account done not exit plz sign in')
    form = AuthenticationForm()
    return render(request, 'app/login.html', {'form':form, 'title':'log in'})

#sends account activation successfully#
def account_activation_sent(request):
    return render(
        request,
        'account_activation_sent.html',
        {
            'title':'Account Activation',
            'message':' An activation email has been sent to your email address, please click on the link to activate your account.',
            'year':datetime.now().year,
        }
    )

#checks if user is registered#
def activate(request, uidb64, token):
    try:
        #uid = force_text(urlsafe_base64_encode(force_bytes(user.pk)).decode())
        #uid = force_text(urlsafe_base64_decode(uidb64)).decode()
        uid=force_text(urlsafe_base64_decode(kwargs["uidb64"]))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.profile.email_confirmed = True #no error handler for this item
        user.save()
        login(request, user)
        return redirect('home')
    else:
        return render(request, 'account_activation_email.html')

def register(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            current_site = get_current_site(request)
            subject = 'Activate Your CarCompare Account'
            message = render_to_string('account_activation_email.html', {
                'user': user,
                'domain': current_site.domain,
                #'uid': urlsafe_base64_encode(force_bytes(user.pk).decode()),
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),
            })
            user.email_user(subject, message)
            #try:
                #sg = sendgrid.SendGridAPIClient(apikey=settings.SENDGRID_API_KEY)
            sg = sendgrid.SendGridAPIClient(apikey='xxxxxxxxxxxxxxxx')
            response = sg.send(message)
            print(response.status_code)
            print(response.body)
            print(response.headers)
            #except Exception as e:
               #print(e.message)

            return redirect('account_activation_sent')
            #send_mail(subject, message, '[email protected]', [email], fail_silently=False)
            #send_mail(subject, message, '[email protected]', ['[email protected]'], fail_silently=False)

    else:
        form = SignUpForm()
    return render(request, 'register.html', {'form': form})


class dealer_reg_view(CreateView): #LoginRequiredMixin

    #def method(self, arg):
        #print(arg)
    model = User
    form_class = GarageProfileForm
    template_name = 'dealer_reg.html'

def dealer_register(request):
    if request.method == 'POST': #combine the 2 views
        dealer_form = GarageProfileForm(request.POST)
        form = SignUpForm(request.POST)
        if form.is_valid() and dealer_form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            dealer_form.save()
            current_site = get_current_site(request)
            subject = 'Activate Your Dealer Account on CarCompare'
            message = render_to_string('account_activation_email.html', {
                'user': user,
                'domain': current_site.domain,
                #'uid': urlsafe_base64_encode(force_bytes(user.pk).decode()),
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),
            })

            user.email_user(subject, message)

            #try:
                #sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
            sg = sendgrid.SendGridAPIClient(apikey='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')
            response = sg.send(message)
            print(response.status_code)
            print(response.body)
            print(response.headers)
            #except Exception as e:
            #    print(e.message)
            return redirect('account_activation_sent')

    else:
        dealer_form = GarageProfileForm()
        form = SignUpForm()
        #dealer_form = GarageProfileForm(instance=request.user.profile)
        #form = SignUpForm(instance=request.user)
    return render(request, 'dealer_reg.html', {
        'dealer_form':dealer_form,
        'form': form,

    })
############### Garage Input #####################
def garageinput(request):
     submitted = False
     if request.method == 'POST':
         form = GarageCarForm(request.POST)
         if form.is_valid():
             form.save()
             return HttpResponseRedirect('/garageinput/?submitted=True')
     else:
         form = GarageCarForm()
         if 'submitted' in request.GET:
             submitted = True
     return render(request,
         'garageinput.html',
         {'form': form, 'submitted': submitted})

Models.py

"""
Definition of models.
"""
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import models
from smart_selects.db_fields import ChainedForeignKey
from django.utils import timezone

################### User Profiles Model ######################

class UserProfiles(models.Model):
    is_garage = models.BooleanField(default=False)
    is_candidate = models.BooleanField(default=False)

class GarageProfile(models.Model):
   # garageID = will be created anyway
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='dealer_profile') 
    #user = models.OneToOneField(User, on_delete=models.CASCADE)
    #bio = models.TextField(max_length=500, blank=True)
    GarageName = models.CharField(max_length=50,default='', blank=False)
    Street = models.CharField(max_length=50,default='', blank=True)
    Town = models.CharField(max_length=30,default='', blank=False)
    County= models.CharField(max_length=30,default='', blank=False)
    Postcode = models.CharField(max_length=8,default='', blank=True)
    Manufacturer = models.CharField(max_length=30,default='', blank=False)
    Website = models.URLField(blank=True,default='')
    email_confirmed = models.BooleanField(default=False,)
    #email_confirmed = models.DateField(null=True, default='',blank=True)
    #add in other fields here as required
    
    def __str__(self):
        return self.GarageName or ''
        return '%s %s' % (self.GarageName, self.Town,) or ''

        

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    #bio = models.TextField(max_length=500, blank=True)
    #location = models.CharField(max_length=30, blank=True)
    email_confirmed = models.BooleanField(default=False)
    #email_confirmed = models.DateField(null=True, blank=True)
    #birth_date = models.DateField(null=True, blank=True)
    #add in other fields here as required

    def __str__(self):
        return self.user or ''


@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()

    def __str__(self):
        return self.user or ''

    ############################ Vehicle Models #############################

class County(models.Model):
    CountyName = models.CharField(max_length=50)
   
    class Meta:
        ordering = ('CountyName',)

class MotorMakes(models.Model):
    MotorMakeName = models.CharField(max_length=50, unique=True, default=False)
    
    def __str__(self):
        return self.MotorMakeName or ''
    
    def __unicode__(self):
        return u'%s' % (self.MotorMakeName) or ''

class MotorModelsV2(models.Model):
    MotorMakeName =  models.CharField(max_length=50, default=False,)
    MotorModelName = models.CharField(max_length=50, default=False,)
    Mkid = models.ForeignKey(MotorMakes,on_delete=models.CASCADE, default=False)
    Mlid = models.IntegerField(default=False, unique=True)
    MotorImage = models.ImageField(upload_to='Car_Pics', default=False,blank=True)
    
    def __str__(self):
        return self.MotorModelName or ''

    def __unicode__(self):
        return u'%s' % (self.MotorModelName) or ''

    class Meta:
        ordering = ('MotorMakeName',)

class MotorDetail(models.Model):
    MotorMakeName = models.CharField(max_length=50, default=False,)
    MotorModelName = models.CharField(max_length=50, default=False,)
    title =  models.CharField(max_length=100, default=False,)
    fuel =  models.CharField(max_length=25, default=False,)
    body = models.CharField(max_length=25, default=False,)
    engine = models.CharField(max_length=5, default=False,)
    Mkid = models.ForeignKey(MotorMakes,on_delete=models.CASCADE, default=False, null=True)
    Mlid = models.ForeignKey(MotorModelsV2,on_delete=models.CASCADE, default=False, null=True)
    RRP = models.DecimalField(max_digits=10, decimal_places=2, default ='0' )
    MotorImage = models.ImageField(upload_to='Car_Pics', default=False,blank=True)

    def __str__(self):
        return self.title or ''
        #return '%s %s' % (self.MotorModelName, self.title,) or ''

    def __unicode__(self):
        return u'%s' % (self.title) or ''

    class Meta:
        ordering = ('MotorMakeName',)
  
  
class GarageInventory(models.Model):
    MotorDetailRef = models.ForeignKey(MotorDetail, on_delete=models.CASCADE, null=True)
    GarageID = models.CharField(max_length=5, default='',)
    ListMake= models.CharField(max_length=50, default='',)
    ListSeries = models.CharField(max_length=50, default='', null=True)
    ListModel= models.CharField(max_length=50,default='')
    #ListSeries = models.ForeignKey(CarSeries, on_delete=models.SET_NULL, null=True)
    #ListModel= models.ForeignKey(CarModel, on_delete=models.SET_NULL, null=True)
    Title = models.CharField(max_length=100, default='', null=True)
    BodyType = models.CharField(max_length=25, default='', null=True)
    GaragePrice = models.DecimalField(max_digits=10, decimal_places=2, default='0')
    FuelType = models.CharField(max_length=15, default='')
    Colour = models.CharField(max_length=15, default='')
    DoorType = models.CharField(max_length=10, default='', null=True)
    CarEngine = models.CharField(max_length=10, default='', null=True)
    Year = models.CharField(max_length=10, default='', null=True)
    created_date = models.DateTimeField(default = timezone.now)
    #Inventory = models.Manager()

    
    def __str__(self):
        return '%s %s %s %s' % (self.GarageID, self.ListModel, self.ListMake, self.Title) or ''
        #return self.Model and self.Title or ''

    def __unicode__(self):
        return u'%s' % (self.Title) or ''

    class Meta:
        ordering = ( 'ListMake','ListModel','Title') 

    #importfile = models.FileField(upload_to='documents/%Y/%m/%d')

    #def __str__(self):
     #   return self.name

**Settings.py --- Shortened **

ROOT_URLCONF = 'DjangoProtoV2.urls'
#'/templates/app'
# Template configuration
# https://docs.djangoproject.com/en/2.1/topics/templates/
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/templates/app/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/templates/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/templates/app/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/templates/static/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/static/app/templates/Static/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/static/app/templates/Static/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/static/app/scripts/',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/app/templates/Static',
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/uploads/'
                    '/home/Johnnyp/DjangoProtoV2_180820/DjangoProtoV2/static/'
                 ],
        #'APP_DIRS': True,


WSGI_APPLICATION = 'DjangoProtoV2.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = "/static/"
STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))

#Media files - car photos#
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/uploads/'
0

There are 0 best solutions below