I am new to using django. In my app, I am uploading images that is being stored to the media folder. Now, I am trying to provide the link for downloading the image which is not working. I also tried to display the image directly( using img in html) which is not working either.
My code is as follows:
urls.py
from django.conf.urls import url
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'workers'
urlpatterns = [
url(r'^$', views.index, name= 'index'),
url(r'^enrollment$',views.enroll, name='enroll'),
url(r'^save_enrollment$',views.save_enrollment, name='save_enrollment'),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
forms.py
from django import forms
from django.forms import ModelForm
from .models import Worker
class Worker_enrollment(forms.ModelForm):
name = forms.CharField(max_length=250)
address = forms.CharField(max_length=500)
phone_number = forms.CharField(max_length=100)
designation = forms.CharField(max_length=1000)
docfile = forms.FileField(label='select an image to upload')
ssn = forms.CharField(max_length=200)
class Meta:
model = Worker
fields = ['name','address','phone_number','designation','docfile','ssn']
models.py:-
from django.db import models
class Worker(models.Model):
name = models.CharField(max_length=250)
address = models.CharField(max_length=500)
phone_number = models.CharField(max_length=100)
designation = models.CharField(max_length=1000)
docfile = models.ImageField(upload_to='documents/')
ssn = models.CharField(max_length=200)
def __str__(self):
return (self.name)
views.py:-
from .models import Worker
from .forms import Worker_enrollment
from django.shortcuts import render, get_object_or_404
from django.conf import settings
def index(request):
workers_info = Worker.objects.all()
context = {
'workers':workers_info
}
return render(request, 'workers/index.html', context)
def enroll(request):
form = Worker_enrollment(request.POST)
if form.is_valid():
return render(request, 'workers/enroll.html', {'form': form})
else:
form = Worker_enrollment()
return render(request, 'workers/enroll.html', {'form': form})
def save_enrollment(request):
worker_info = Worker()
if request.method == 'POST':
form = Worker_enrollment(request.POST,request.FILES)
if form.is_valid():
worker_info.name = form.cleaned_data['name']
worker_info.address = form.cleaned_data['address']
worker_info.designation = form.cleaned_data['designation']
worker_info.phone_number = form.cleaned_data['phone_no']
worker_info.ssn = form.cleaned_data['ssn']
worker_info.docfile = request.FILES['docfile']
worker_info.save()
return render(request,'workers/saves_worker.html',{'worker_info':worker_info})
else:
form = Worker_enrollment()
return render(request, 'workers/saves_worker.html', {'worker_info': worker_info})
enroll.html:-
<form action="save_enrollment" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_ul }}
<input type="submit" value="Submit" />
</form>
saves_worker.html:-
<h1>Worker has been enrolled</h1>
<br>
<h2>Name - {{worker_info.name}}</h2><br>
<h2>PhoneNo - {{worker_info.phone_number}}</h2><br>
<h2>Designtion - {{worker_info.designation}}</h2><br>
<h2>SSN - {{worker_info.ssn}}</h2>
<h2>Address - {{worker_info.address}}</h2>
<h2><a href="{{ worker_info.docfile.url }}" >worker's image</h2>
The following are specified in the settings.py file:-
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
Are you sure your save_enrollment function saves the image in docfile field of the worker_info. Try using:
def save_enrollment(request):
if request.method == 'POST':
form = Worker_enrollment(request.POST,request.FILES)
if form.is_valid():
worker_info = form.save()
return render(request,'workers/saves_worker.html',{'worker_info':worker_info})
else:
form = Worker_enrollment()
return render(request, 'workers/saves_worker.html', {'worker_info': worker_info}
You dont need to define the fields again in your modelform. Also you are using FileField in the form instead of ImageField. If you want to add extra field in the form, you need to add those fields in __init__() method of form.
Try with the following:
class Worker_enrollment(forms.ModelForm):
class Meta:
model = Worker
fields = ['name','address','phone_number','designation','docfile','ssn']
Extra tip: Dont use CharField with max_length=1000. CharField should be used upto 255 characters. If you need more length use TextField instead. You also need to install Pillow library in order to make images visible.
I just solved my problem by changing the MEDIA_URL as follows:
MEDIA_URL = 'shield/media/'
The name of my project is shield.
Related
I'm new to django. I've been stuck for a while. I believe everything is configured correctly. However, when my objects are created it is not creating the media directory or storing the files/images. I have done the settings file, urls, views, models, forms everything.
Here are relevant files:
// setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
// models.py
class Trip(models.Model):
city = models.CharField(max_length= 255)
country = models.CharField(max_length= 255)
description = models.CharField(max_length= 255)
creator = models.ForeignKey(User, related_name = 'trips_uploaded',on_delete= CASCADE, null=True)
favoriter = models.ManyToManyField(User, related_name= 'fav_trips')
photo = models.ImageField(null=True, blank =True, upload_to='trips/')
// urls.py ( there were 2 ways to write media according to tutorial)
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('travelsiteapp.urls'))
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
// views.py (lastly)
def tripAdd(request):
form = TripForm()
if request.method == 'POST':
form = TripForm(request.POST, request.FILES)
if form.is_valid():
form.photo = form.cleaned_data["photo"]
form.save()
context = { 'form': form}
return render(request, 'tripAdd.html', context)
// html/ form
<form action="/createTrip"method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="submit">
</form>
// forms.py
from django import forms
from django.forms import ModelForm
from .models import Trip
from django import forms
class TripForm(ModelForm):
class Meta:
model = Trip
fields = ['city', 'country', 'description', 'photo']
// I have hit all the steps not sure whats wrong? & and installed pip pillow
Which url is serving the tripAdd() view? If it is /createTrip as in your form, then add a trailling slash in the action like this: /createTrip/. When you post to an URL, Django expects a trailing slash by default. You can customize that behavior if you like. Also, don't forget to declare this URL (since it is not in the example you provided).
I've gone through about 8 tutorials across YouTube and Online websites. I believe everything is configured correctly. However, when my objects are created it is not creating the media directory or storing the files. I have done the settings file, urls, views, models everything.
Here are relevant files:
// setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
// models.py
class Trip(models.Model):
city = models.CharField(max_length= 255)
country = models.CharField(max_length= 255)
description = models.CharField(max_length= 255)
creator = models.ForeignKey(User, related_name = 'trips_uploaded',on_delete= CASCADE, null=True)
favoriter = models.ManyToManyField(User, related_name= 'fav_trips')
photo = models.ImageField(null=True, blank =True, upload_to='trips')
// urls.py ( there were 2 ways to write media according to tutorial)
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('travelsiteapp.urls'))
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
// views.py (lastly)
def tripAdd(request):
form = TripForm()
if request.method == 'POST':
form = TripForm(request.POST, request.FILES)
if form.is_valid():
form.photo = form.cleaned_data["photo"]
form.save()
context = { 'form': form}
return render(request, 'tripAdd.html', context)
// html/ form
<form action="/createTrip"method="post" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="submit">
</form>
// forms.py
from django import forms
from django.forms import ModelForm
from .models import Trip
from django import forms
class TripForm(ModelForm):
city = forms.TextInput()
country = forms.TimeField()
description = forms.Textarea()
photo = forms.ImageField()
class Meta:
model = Trip
fields = ['city', 'country', 'description', 'photo']
// I have hit all the steps not sure whats wrong? & and installed pip pillow
Within your forms.py it's not necessary to recreate the existing fields from your model.
class TripForm(ModelForm):
# city = forms.TextInput()
# country = forms.TimeField()
# description = forms.Textarea()
# photo = forms.ImageField()
# The above is not necessary here...
class Meta:
model = Trip
# These it should be since the model does have these fields
fields = ['city', 'country', 'description', 'photo']
However, within your views.py file in the tripAdd method, that line where I'm seeing where you have form.photo = form.cleaned_data['photo'] that's not necessary also. Just comment/remove that line and just call the save method on the form.
form = TripForm(request.POST, request.FILES)
if form.is_valid():
# form.photo = form.cleaned_data["photo"]
form.save()
Additionally, I'd suggest using a / when dealing with folders as best practice.
On the Trip model:
photo = models.ImageField(upload_to='trips/', null=True, blank =True)
In the project's urls.py add the following:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('travelsiteapp.urls'))
] # + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Adding the media url/path if Debug is true
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I have model where I can upload files without problem, and a model forms which upload the file, which get the path perfectly when I call them in a html loop; but this files can't be accessed by django admin interface. In the two cases the uploaded files can by get in the defined media_root.
What am I doing wrong?
models.py
class Documentos(models.Model):
user = models.OneToOneField(User, on_delete="models_CASCADE", null=True, blank=True)
nome = models.CharField(max_length=200, default='Arquivo')
documento = models.FileField(upload_to='')
data = models.DateField(auto_now_add=True)
formatado = models.BooleanField(default=False)
class Meta:
verbose_name = 'Documento'
verbose_name_plural = 'Documentos'
def __str__(self):
return self.nome
forms.py
class DocumentosForm(forms.ModelForm):
class Meta:
model = Documentos
fields = ['user','nome','documento']
views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from .forms import *
from .models import *
def alfa(request):
return render(request, 'pdfupload.html')
# Create your views here.
#login_required(login_url='/register')
def upload(request):
context = {}
if request.method == 'POST':
uploaded_file = request.FILES['document']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
context['url'] = fs.url(name)
return render(request, 'pdfupload.html', context)
def documentos_lista(request):
return render(request, 'lista.html')
def upload_documento(request):
return render(request, 'documento_upload.html')
forms.html:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="document" />
<input type="submit" name="submit" value="Upload" />
</form>
I have my project/urls.py:
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I am using django 2.1
Even I can't get the uploadedfiles by forms in django admin, no error message is returned.
I am very grateful for your help. Thank you, have a nice day.
i have a problem with django. I need to display my files in single page
So i create model:
class UserProfile(models.Model):
profile_img = models.ImageField(upload_to='media/images/', blank=True, null=True)
profile_text = models.TextField()
profile_title = models.CharField(max_length=300)
profile_user = models.ForeignKey(User)
and form
class ProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ['profile_img', 'profile_title']
then view
def cabinet(request):
form = ProfileForm(request.POST, request.FILES or None)
if request.method == 'POST' and form.is_valid():
obj = UserProfile(profile_img=request.FILES['profile_img'])
obj = form.save(commit=False)
obj.profile_user = request.user
obj.save()
return redirect(reverse(cabinet))
return render(request, 'cabinet.html', {'form': form})
I try use view
def user_page(request):
profile = UserProfile.objects.all()
return render(request, 'user_page.html', {'profile':profile})
and
{% for img in profile %}
{{ img.profile_img }}
{% endfor %}
it is not work
Help me plz, i try to read documentation but it doesn't help
So the code you pasted will only print path to your each profile.profile_img. And so is the profile_img attribute, it only stores a path to the image you uploaded, not the image itself. In order to use the media files uploaded to your website you need to specify a MEDIA_ROOT and MEDIA_URL in your settings.py.
Then you need to append it to your urls.py. You might want to look here also: show images in Django templates
After you have done so, to display an image in template just use HTML tag
<img src="{{MEDIA_URL}}{{ img.profile_img }}" />
I did it, as you said. Image doesn't display. I inspect element in browser: it should work
my settings:
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
And i have 2 urls, main file for my project:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^/cabinet', include('comments.urls') ),
url(r'^', include('user_login.urls')),]
and for my app:
urlpatterns = [
url(r'^$', views.cabinet, name='cabinet' ),
url(r'^/user_page/$', views.user_page, name='user_page'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I had the same problem, and i just def a str for my pic field to return the self.pic.url in the model itself, and in the template i just used {{pic}}.
Please correct this line
MEDIA_URL = '/media/' MIDIA_ROOT = os.path.join(BASE_DIR, 'media')
to
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
it should be MEDIA not MIDIA
My view is a function based view (it is a legacy and due to inline formset usage it is easier to keep it that way, rather than CBV). My goal is to be able to render the ModelForm for the model object Article.objects.get(user=user).latest("id") and with the POST method, update the same object that has been rendered. The issue is that the ModelForm "does not remember" the object it corresponded to. What would be the right way to pass that info about the object to the view for use in the POST method?
Below is the simplified version of the views.py and the urls.py
views.py
from django.contrib.auth.models import User
from django.shortcuts import render_to_response
from django.template import RequestContext
from specify.models import Article
from specify.forms import ArticleForm
def index(request):
user = User.objects.get(username=request.user.username)
if request.method == "POST":
a_form = ArticleForm(request.POST, instance= *???* )
a_form.save()
else:
a = Article.objects.get(user=user).latest("id")
a_form = ArticleForm(instance=a)
return render_to_response(
"specify/index.html",
{
"a_form" : a_form,
},
context_instance=RequestContext(request)
)
urls.py
from django.conf.urls import patterns, url
from specify import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index')
)
EDIT1: added models.py and forms.py
models.py
from django.db import models
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
forms.py
from django.forms import ModelForm
from specify.models import Article
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content']
First you should pass article id to the template, in view.py
def index(request):
user = User.objects.get(username=request.user.username)
if request.method == "POST":
#Explained later
else:
a = Article.objects.get(user=user).latest("id")
a_form = ArticleForm(instance=a)
article_id = a.id
return render_to_response(
"specify/index.html",
{
"a_form" : a_form,
"article_id": article_id,
},
context_instance=RequestContext(request)
)
Second in your template inside of your form html element you should handle your article id
{% if article_id %}
<input type="hidden" value='{{ article_id }}' id='article_id' name='article_id'/>
{% endif %}
Thirdly in update handling you should do following:
if request.method == "POST":
article_id = request.POST.get('article_id') # You are getting passed article id
a = Article.objects.get(pk=article_id) # You are getting instance by id
a_form = ArticleForm(request.POST, instance=a)
a_form.save()
Try above steps and if you have problem leave a comment