Image won't load in Flask App static folder - html

I am trying to add an image to the header of my app and it will not load. I have the image stored in the static folder which is at the same level as the app.py file. The code that should display the image is:
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<img src="{{url_for('static', filename='marco_icon.png')}}" />
<ul class="nav nav-pills">
<li class="nav-item">Home</li>
</ul>
</header>
when I open the app it appears as an error icon:
When I inspect the element it shows:
app.py code is as follows:
from myproject import app
from flask import render_template
#app.route('/')
def index():
return render_template('home.html')
if __name__ == '__main__':
app.run(debug=True)
init.py is as follows:
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
Migrate(app,db)
from myproject.trips.views import trips_blueprint
app.register_blueprint(trips_blueprint,url_prefix='/trips')
Directory structure:
Any thoughts on what I am doing wrong would be appreciated!

Related

Django reverse for 'password_change_done' not found

I have a small application that I'm writing, but I have came into some trouble with the password changing elements used with the Django authentication framework. But I always get the error after changing a password that: Reverse for 'password_change_done' not found. 'password_change_done' is not a valid view function or pattern name. Here is my code below:
#account urls.py
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
app_name = 'account'
urlpatterns = [
#Password Changes URLs
path('password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]
This is my directory structure for the login system:
Directory Structure
Here's the password_change.html file:
<h3 style="text-align: center;">Change your password</h3>
<div class="login-form" style="text-align: center; ">
<form method="post">
{{ form.as_p }}
<p><input type="submit" value="Change"></p>
{% csrf_token %}
</form>
</div>
Any help would be greatly appreciated!
Since you use an app_name, you will need to include the namespace in the success_url of the PasswordChangeView:
# account urls.py
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
from django.urls import reverse_lazy
app_name = 'account'
urlpatterns = [
#Password Changes URLs
path('password_change/', auth_views.PasswordChangeView.as_view(
success_url=reverse_lazy('account:password_change_done')
), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]
some other class-based views of the auth package have success_urls, these thus should be updated as well.

Getting Django CSRF error with raw html form

I'm trying to set up a raw html form where a user can make a suggestion and then save it on a database with a POST method, but I keep getting a Forbidden (403) CSRF verification failed. Request aborted. even after following the steps in the Help section.
I have found that I don't get the error if I add csrf_exempt on top of my view like this:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def suggest_ptags(request):
context = {}
print("Form is submitted.")
return render(request, "partials/search_form.html", context)
But I was made aware that It removes completly the CSRF protection and I don't want that.
So what should I do?
Here's my search_form.html form in a partials folder in templates:
<!-- Suggestion Form in popup -->
<div class="prop-modal">
<div class="prop-content">
<a class="btn-close-prop">×</a>
<img src="{% static 'images/pyramids.svg' %}">
<form action="/suggest_ptags/" class="feedback-form" method="POST" enctype="text/plain">
{% csrf_token %}
<h5 class="title-prop">Suggestion</h5>
<input class="input-prop" name="suggest" rows="3" cols="37" placeholder="suggest something..."></input>
<input class="button-prop" type="submit" value="Envoyez"></input>
</form>
</div>
</div>
My current Views.py:
from django.views.decorators.csrf import ensure_csrf_cookie
#ensure_csrf_cookie
def suggest_ptags(request):
context = {}
print("Form is submitted.")
return render(request, "partials/search_form.html", context)
And in my Urls:
from django.conf.urls import url
from django.contrib import admin
from search.views import HomeView, ProductView, FacetedSearchView, autocomplete, suggest_ptags
from .settings import MEDIA_ROOT, MEDIA_URL
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', HomeView.as_view(), name='home'),
url(r'^admin/', admin.site.urls),
url(r'^suggest_ptags/$', suggest_ptags, name='suggest_ptags'), #Suggestions
url(r'^product/(?P<slug>[\w-]+)/$', ProductView.as_view(), name='product'),
url(r'^search/autocomplete/$', autocomplete),
url(r'^search/', FacetedSearchView.as_view(), name='haystack_search'),
] + static(MEDIA_URL, document_root=MEDIA_ROOT)
Any solutions?
You shouldn't use enctype="text/plain". You can remove it (which is the same as enctype="multipart/form-data"), or use enctype="multipart/form-data" if you are uploading files.

How to fix this for_url error ("SyntaxError: '/upload' is not a valid selector") in Flask?

I have the following problem in Flask,
In my templates folder-
I have three HTML files:
index.html
database.html
upload.html
server.py
from flask import Flask, url_for,redirect, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload')
def upload():
return render_template('upload.html')
#app.route('/database')
def database():
return render_template('database.html')
if __name__ == '__main__':
app.run(debug=True)
index.html
<a class="nav-link js-scroll-trigger" href="{{ url_for('upload')}}">Upload File</a>
<a class="nav-link js-scroll-trigger" href="{{ url_for('database')}}">Protein Database</a>
The error I get on the web console on Firefox:
SyntaxError: '/upload' is not a valid selector bootstrap.bundle.min.js:6
Error from Chrome:
Failed to execute 'querySelector' on 'Document': '/upload' is not a valid selector.
at Object.getSelectorFromElement
How can I fix this error please, any help would be greatly appreciated
Many Thanks,
Ishack

Unable to call Django function for inserting data in postgres db

I am running the below code however when i submit create.html template it goes directly to home.html without inserting any record in postgres db. I believe, the function "create" is not called at all. Kindly assist
I tried directing the function
* views.py *
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Product
def home(request):
return render(request, 'products/home.html')
#login_required
def create(request):
if request.method =='POST':
product = Product()
product.title = request.POST['title']
product.save()
return redirect('home')
else:
return render(request, 'products/create.html')
* urls.py *
from django.urls import path,include
from . import views
urlpatterns = [
path('create',views.create,name='create'),]
* models.py *
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
* apps.py *
from django.apps import AppConfig
class ProductsConfig(AppConfig):
name = 'products'
* Main url.py *
from django.contrib import admin
from django.urls import path,include
from products import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('products/', include('products.urls')),]
* urls.py *
from django.urls import path,include
from . import views
urlpatterns = [
path('create',views.create,name='create'),]
* create.html *
{%extends 'base.html'%}
{%block content%}
<form method="POST" action="{% url 'create' %}" enctype = "multipart/form-data">
{% csrf_token %}
Title:
<br/>
<input type="text" name = "title"/>
<br/><br/>
<input type="submit" class = "btn btn-primary" value = "Add Product"/>
</form>
{%endblock%}
I was expecting the record to be inserted in database (postgres) and I should be able to validate it using "django administration" page.
I am able to add the record manually via "django administration" page but not via above html form

"Page not found (404)" when clicking on follow or unfollow button

urls.py
"""stratinum URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin
from imagec import views as imagec_views
from contact import views as contact_views
from django.conf.urls.static import static
from django.conf import settings
from django.core.urlresolvers import reverse
admin.autodiscover()
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', imagec_views.home, name='home'),
url(r'^about/$', imagec_views.about, name='about'),
url(r'^detail/$', imagec_views.detail, name='detail'),
url(r'^profile/$', imagec_views.userProfile, name='profile'),
url(r'^create_form/$', imagec_views.create_form, name='create_form'),
url(r'^contact/$', contact_views.contact, name='contact'),
url(r'^userProfile/$', contact_views.contact, name='userProfile'),
url(r'^accounts/', include('allauth.urls')),
url('', include('social.apps.django_app.urls', namespace='social')),
url('', include('django.contrib.auth.urls', namespace='auth')),
url(r'^$', imagec_views.ListaFollow, name="lista_follow"),
url(r'^add_follow/(?P<id>\d{1,})/$', imagec_views.AddFollow, name='add_follow'),
url(r'^remove_follow/(?P<id>\d{1,})/$', imagec_views.RemoveFollow, name='remove_follow')
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse
from django.shortcuts import render, get_object_or_404
from .forms import AlbumForm
from .models import Album
from django.http import HttpResponse,HttpResponseForbidden
IMAGE_FILE_TYPES = ['png', 'jpg', 'jpeg']
# Create your views here.
def home(request):
context = {}
template = 'home.html'
return render(request, template, context)
def about(request):
context = {}
template = 'about.html'
return render(request, template, context)
#login_required()
def userProfile(request):
user = request.user
context = {'user': user}
template = 'profile.html'
return render(request, template, context)
def create_form(request):
form = AlbumForm(request.POST or None, request.FILES or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.image= request.FILES['image']
file_type = album.image.url.split('.')[-1]
file_type = file_type.lower()
if file_type not in IMAGE_FILE_TYPES:
context = {
'album': album,
'form': form,
'error_message': 'Image file must be PNG, JPG, or JPEG',
}
return render(request, 'detail.html', context)
album.save()
return render(request, 'create_form.html', {'album': album})
context = {
"form": form,
}
return render(request, 'create_form.html', context)
def detail(request):
user = request.user
#album = get_object_or_404(Album, pk=id)
return render(request, 'detail.html', {'user': user})
from django.shortcuts import render, redirect
from .models import MyUser
from django.views.generic import TemplateView,View
from django.db.models import Q
from django.core.urlresolvers import reverse
from . import models
#from imagec.models import User
from django.contrib.auth.models import Permission, User
class ListaFollow(TemplateView):
template_name = 'lista_follow.html'
def get_context_data(self,**kwargs):
context = super(ListaFollow,self).get_context_data(**kwargs)
context['all'] = MyUser.objects.all()
context['me'] = User.objects.get(username=self.request.user)
context['notme'] = MyUser.objects.filter(follow__username=self.request.user)
context['notfollow'] = MyUser.objects.filter(~Q(follow__username=self.request.user))
return context
class AddFollow(View):
def get(self,request, id):
me=models.MyUser.objects.get(username=request.user)
followed = models.MyUser.objects.get(id=id) #el wey
me.follow.add(followed)
return redirect(reverse('imagec/about.html'))
class RemoveFollow(View):
def get(self,request, id):
me=models.MyUser.objects.get(username=request.user) #instancia del usuario con el id que quiero crear
followed = models.MyUser.objects.get(id=id)
me.follow.remove(followed) #creo el usuario con mi nombre y la relacion
return redirect(reverse('imagec/about.html'))
models.py
from __future__ import unicode_literals
from django.contrib.auth.models import Permission, User
from django.db import models
# Create your models here.
class profile(models.Model):
name = models.CharField(max_length=120)
description = models.TextField(default='description default text')
def __unicode__(self):
return self.name
class Album(models.Model):
user = models.ForeignKey(User, default=1)
image = models.FileField()
class MyUser(models.Model):
user = models.ForeignKey(User)
username = models.CharField(max_length=200)
follow = models.ManyToManyField('self', blank=True)
def __unicode__(self):
return self.username
about.html
{% extends 'base.html' %}
{% block content %}
<body>
<div class="container">
<h1>Profile</h1>
<p>Username: {{ user }}</p>
<p>Email: {{ user.email }}</p>
<p><input type="submit" value="Upload"/></p>
</div>
<table>
<tr>
<th colspan="3"> # {{ user }}</th>
</tr>
<tr>
<td colspan="3">
<span> Follows </span>
</td>
</tr>
<td>{{follow}} <a href="add_follow/{{user.id}}">
<button>Follow</button></a></td>
<td>{{follow}} <a href="remove_follow/{{user.id}}">
<button>Unfollow</button></a></td>
</a>
<tr>
<td colspan="3">
<span> Unfollows </span>
</td>
</tr>
</table>
</body>
{% endblock %}
When I run this code I will get error as:
"Not Found: /about/add_follow/1
[22/Apr/2017 07:26:25] "GET /about/add_follow/1 HTTP/1.1" 404 6063"
in the terminal.
This happening because you are using relative url to create a link to the follow/unfollow page. To fix this, you can either make it an absolute url or use django's url reverser.
Making the link absolute:
<td>{{follow}} <a href="/add_follow/{{user.id}}">
<button>Follow</button></a></td>
<td>{{follow}} <a href="/remove_follow/{{user.id}}">
<button>Unfollow</button></a></td>
Making use of the url tempalte tag
<td>{{follow}} <a href="{% url 'add_follow' id=user.id %}">
<button>Follow</button></a></td>
<td>{{follow}} <a href="{% url 'remove_follow' id=user.id %}">
<button>Unfollow</button></a></td>
Read about Absolute and Relative urls