How to save uploaded files to models and serve them in templates? - django

I've been following the django 2 official tutorial but I'm a bit confused as how to work with images and uploaded files.
I have a project with a few apps. Let's call the project myProj and the app myApp. There is a model in myApp called myModel which has an image field myImage.
Here is my model:
from django.db import models
class myModel(models.Model):
myImage = models.ImageField(upload_to='myApp_images')
Here is my template:
<img src="{{ n.image }}"></img>
Here is my view
from django.shortcuts import get_object_or_404, render
from .models import myModel
def index(request):
n = myModel.objects[0]
context = {
'n': n,
}
return render(request, 'myModel/index.html', context)
And here is my settings:(parts I thought were relevant)
INSTALLED_APPS = [
'news.apps.myModelConfig',
'django.contrib.staticfiles',
]
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/aran/myfiles/projects/futureCoin/media/'
Here is my myProject/urls.py:
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('myModel/', include('myModel.urls')),
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
So I made an instance of the model through the django admin site.
Here is the directory tree after that(I removed the pycache):
.
├── myProject
│   ├── __init__.py
│   ├── models.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── media
│   └── myModel_images
│   └── myImage.jpeg
├── myModel
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── myModel
│   │   ├── images
│   │   │   └── bg.jpg
│   │   └── style.css
│   ├── templates
│   │   └── myModel
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
Now the problem is that when I try to open the index page the image is not shown because the url to it is: http://127.0.0.1:8000/myModel/myModel_images/myImage.jpg
however if I manualy open the url:http://127.0.0.1:8000/media/myModel_images/myImage.jpg I see the right Image. Can anyone please help me understand where the problem is and how I can fix it? Any other feedback on my code would also be much appreciated.

What happens when I do n.image and why does it give me a url but a wrong url?
It's not a wrong url at all. That's because n.image returns the url path of the image like /path/to/image.jpg exactly the way that you have set up in your ImageField upload_to
myImage = models.ImageField(upload_to='myApp_images')
by default this will be prefixed by your url address and becomes 127.0.0.1:8000/path/to/image.jpg. As you can see it misses the /media/ as provided in settings.MEDIA_URL where your all images are localized.
So now by using {{ n.image.url}}, you actually call it from your settings configuration, your MEDIA_URL /media/ will be added as prefix and becomes /media/path/to/image.jpg prefixed by the url 127.0.0.1:8000
To fix it, in your template, access the image url with {{instance.field.url}}
try:
<img src="{{ n.image.url }}"></img>
instead of
<img src="{{ n.image }}"></img>

Related

Create react app + Django deployment Uncaught SyntaxError: Unexpected token <

I've been trying to deploy an app to pythonanywhere but the page is just blank, because main.6f259c1b.js file throws error`
Uncaught SyntaxError: Unexpected token <
`
I've been following the instuctions on this article https://www.fusionbox.com/blog/detail/create-react-app-and-django/624/ and this https://www.techiediaries.com/create-react-app-django/
both articles suggest to create a view with following content
class FrontendAppView(View):
"""
Serves the compiled frontend entry point (only works if you have run `yarn
run build`).
"""
def get(self, request):
try:
with open(os.path.join(settings.REACT_APP_DIR, 'build', 'index.html')) as f:
return HttpResponse(f.read())
except FileNotFoundError:
logging.exception('Production build of app not found')
return HttpResponse(
"""
This URL is only used when you have built the production
version of the app. Visit http://localhost:3000/ instead, or
run `yarn run build` to test the production version.
""",
status=501,
)
and in app website/urls.py
urlpatterns = [
url(r'^', FrontendAppView.as_view())
]
Those instructions don't work for me. It's something that related to pushState routing, react-routing, I don't know. My app works ok in development server in localhost:3000, it only seen in pythonanywhere and local apache server with mod_wsgi.
This is my config of local apache(from Django documentation):
WSGIScriptAlias / /home/user/projects/myproject/myproject/wsgi.py
WSGIPythonHome /home/user/.virtualenvs/myproject
WSGIPythonPath home/user/projects/myproject/
<Directory /home/user/projects/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
This is root
DocumentRoot "/srv/http"
Part of my settings
REACT_APP_DIR = os.path.join(BASE_DIR, 'frontend')
STATIC_URL = '/static/'
STATIC_ROOT = 'static'
STATICFILES_DIRS = [
os.path.join(REACT_APP_DIR, 'build', 'static')
]
All software are latest release.
Maybe this comment solves my problem, I just don't understand it. https://github.com/facebookincubator/create-react-app/issues/1812#issuecomment-286511320
This is my localhost screenshot
My project directory structure
├── api_v0
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── myproject
│   ├── __init__.py
│   ├── local.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── frontend
│   ├── build
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── public
│   ├── README.md
│   └── src
├── manage.py
├── requirements.txt
├── static
│   ├── admin
│   ├── css
│   ├── js
│   ├── media
│   └── rest_framework
└── website
├── admin.py
├── apps.py
├── __init__.py
├── management
├── middleware.py
├── migrations
├── models.py
├── __pycache__
├── tests.py
├── urls.py
└── views.py
Review the styles referenced on the page and make sure that all the CSS files are referenced on the page using a <link> tag and not a <script> tag.
reference
also there are nginx adubting , you can do it for request your site adminstator help

Redirect url from django application

I have a basic application built in Django, which only works if I enter:
http://xx.xx.xxx.xx/polls. How can I rewrite this in my urls.py file so that http://xx.xx.xxx.xx/polls will redirect me to http://xx.xx.xxx.xx/ ?
My urls.py file for the main project:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
]
My urls.py file from the application:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
]
My project structure:
├── blog
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── settings.py
│   ├── settings.pyc
│   ├── urls.py
│   ├── urls.pyc
│   ├── wsgi.py
│   └── wsgi.pyc
├── db.sqlite3
├── manage.py
├── polls
│   ├── admin.py
│   ├── admin.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── 0001_initial.pyc
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── models.py
│   ├── models.pyc
│   ├── templates
│   │   └── polls
│   │   ├── detail.html
│   │   ├── index.html
│   │   ├── results.html
│   │   └── static
│   │   └── polls
│   │   ├── css
│   │   │   ├── semantic.css
│   │   │   ├── semantic.min.css
│   │   │   ├── sidebar.css
│   │   │   ├── sidebar.min.css
│   │   │   ├── sidebar.min.js
│   │   │   └── style.css
│   │   ├── images
│   │   └── js
│   │   ├── jquery-1.11.2.min.js
│   │   ├── semantic.js
│   │   ├── semantic.min.js
│   │   ├── sidebar.js
│   │   └── sidebar.min.js
│   ├── tests.py
│   ├── tests.pyc
│   ├── urls.py
│   ├── urls.pyc
│   ├── views.py
│   └── views.pyc
├── readme.txt
├── requirements.txt
├── templates
│   └── admin
│   └── base_site.html
As far as I undesrstand you don't ant to redirect from /polls/ to / but want to show the polls index at the home page. If so then just move the index url from the polls/urls.py into the main urls.py:
from polls.views import IndexView
urlpatterns = [
url(r'^$', IndexView.as_view(), name='index'),
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
]
UPDATE: It is a bad practice to use hard-coded urls in the django templates/code. You should always use the {% url %} template tag and the reverse() function. This will allow you to change urls as you want without breaking the code.
So link to the index page should be like this:
Home page
And, for example, link to the poll details:
Poll #{{ poll.pk }}
In the model's get_absolute_url() method use the reverse().
You could also include your whole polls app on '/' by doing:
url(r'^', include('polls.urls', namespace="polls")),
Also, see here for more information on redirecting in urls.py:
Redirect to named url pattern directly from urls.py in django?
In your case it would be something like:
from django.views.generic import RedirectView
url(r'^polls/', RedirectView.as_view(pattern_name='polls:index')

Django - how to wire urls correctly? url(), include(), ImportError

I try to structure my project by putting applications under an "apps" folder, like so:
├── manage.py
├── mysite
│   ├── apps
│   │   ├── __init__.py
│   │   ├── myapp1
│   │   │   ├── __init__.py
│   │   │   ├── models.py
│   │   │   ├── urls.py
│   │   │   └── views.py
│   │   └── myapp2
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
And in mysite/urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^myapp1/', include('mysite.apps.myapp1.urls')),
url(r'^mysite/apps/myapp2/', include('myapp2.urls')),
url(r'^admin/', include(admin.site.urls)),
)
There is something wrong with:
url(r'^myapp1/', include('mysite.apps.myapp1.urls')),
url(r'^mysite/apps/myapp2/', include('myapp2.urls')),
I could not wire either myapp1 or myapp2 correctly, Django gives me "ImportError...no module named myapp1..." Any help?
You're missing a level in the relative path:
url(r'^mysite/apps/myapp2/', include('apps.myapp2.urls')),
myapp1 looks like it should work to me.
A note, comparing how you're trying to include myapp1 vs myapp2, it looks like you may have misunderstood the structure slightly. The URL has nothing to do with the code layout. This is completely valid:
url(r'^zimzam/allthethings/', include('apps.myapp2.urls')),
maybe like this:
include('mysite.apps.myapp1.urls')),
update
you can try:
add a file __init__.py in the mysite dir

Newbie Django urls, views, and templates - how can this incredibly simple django project possibly be failing?

When the user lands at http://127.0.0.1:8000/ I would like to display an html page that says "welcome." When the user goes http://127.0.0.1:8000/time/ I would like to display the current time. I have followed instructions to the t and dotted every i. My settings are below. Why do I continue to get a TemplateDoesNotExist error?
views.py
from django.template.loader import get_template
from django.shortcuts import render
import datetime
def current_datetime(request):
now = datetime.datetime.now()
current_datetime_template = get_template('current_datetime.html')
context_dict = {'current_date': now}
return render(request, current_datetime_template, context_dict)
def welcome(request):
welcome_template = get_template('welcome.html')
context_dict = {'username' : 'Sally Jenkins'}
return render(request, welcome_template, context_dict)
urls.py
from django.conf.urls.defaults import patterns, include, url
from simpletest.views import welcome, current_datetime
urlpatterns = patterns('',
url(r'^time/$', current_datetime),
url(r'^$', welcome),
)
settings.py
... # all defaults ommitted here - I changed nothing.
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
In my django project directory I have a directory called templates and it contains base.html, current_datetime.html, and welcome.html just as expected.
Please tell me what I have overlooked.
Thanks.
MORE INFO:
I am using virtualenv. Does the fact that I have two django projects in the /Users/quanda/dev/django-projects/ make any difference? I can't imagine it would. One is called "blossom" and is the main project I am working on. The other is called "simpletest" and I made it extremely simple so that I could isolate the issue I was having in my blossom project. I am using the same virtual environment for both projects. Running tree -L 2 from django-projects/ gives the following structure:
.
├── Procfile
├── blossom
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── fixtures
│   ├── manage.py
│   ├── onora
│   ├── settings.py
│   ├── settings.pyc
│   ├── sqlite3-database
│   ├── templates
│   ├── test_stuff.py
│   ├── urls.py
│   ├── urls.pyc
│   ├── views.py
│   └── views.pyc
├── requirements.txt
├── simpletest
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── manage.py
│   ├── settings.py
│   ├── settings.pyc
│   ├── templates
│   ├── urls.py
│   ├── urls.pyc
│   ├── views.py
│   └── views.pyc
└── virtual_environment
├── bin
├── django-registration-0.8-alpha-1.tar
├── include
└── lib
You're passing a template object instead of the template name, as shown here in the traceback:
/Users/quanda/dev/django-projects/simpletest/templates/<django.template.base.Template object at 0x102963910> (File does not exist)
...
File "/Users/quanda/dev/django-projects/simpletest/../simpletest/views.py" in current_datetime
9. return render(request, current_datetime_template, context_dict)
Don't pass the variable current_datetime_template - just pass 'current_datetime.html' as a string, like so:
def current_datetime(request):
now = datetime.datetime.now()
context_dict = {'current_date': now}
return render(request, 'current_datetime.html', context_dict)
Try something like this in settings.py:
CURRENT_PATH = os.path.abspath(os.path.dirname(__file__) # for linux
# or
CURRENT_PATH = os.path.abspath(os.path.dirname(__file__).replace('\\', '/') # for windows
TEMPLATE_DIRS = (os.path.join(CURRENT_PATH, 'templates'),) # for template dirs
Suppose foobar is your django project. Then welcome.html should be resides in /foobar/templates/welcome.html
and In settings:
TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__),"templates"),
) #for linux and windows

How does django know where to load login.html

I have used the following steps to create a login page.
1> create the urls.py
urlpatterns = patterns('',
(r'^$', main_page),
(r'^login/$', 'django.contrib.auth.views.login'),
)
2> create registration/login.html
3> load http://127.0.0.1:8000/login/ then I see the created login.html.
Also my directory structure is as follows:
.
├── bookmarks
│   ├── forms.py
│   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── bookmarksdb
├── __init__.py
├── manage.py
├── settings.py
├── site_media
│   └── style.css
├── templates
│   ├── base.html
│   ├── main_page.html
│   ├── registration
│   │   ├── login.html
│   │   ├── logout_success.html
│   │   ├── register.html
│   │   └── register_success.html
│   ├── user_page.html
└── urls.py
Question> How does django know to connect the http://127.0.0.1:8000/login/ with template\registration\login.html?
Thank you
if you look in django.contrib.auth.views.py you'll find
def login(request, template_name='registration/login.html'),
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
"""
Displays the login form and handles the login action.
"""
it's simply the default template path, which you can override should you wish