Upload File in Django (not working) - django

I am creating a bulletin here containing threads. Each thread includes one image and then the thread can be extended with posts.
It's like 4chan.
The models isn't saved in the database. I followed this answer to create an file upload example.
The forum app contains a simple file upload example and the upload objects do get saved there.
Codebase (github)
The project tree
bookstore/
chan/
templates/chan/index.html
forms.py
admin.py
views.py
urls.py
forum/
...
bookstore/
settings.py
urls.py
Settings
.
.
.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Urls.py
from django.conf.urls import url, include
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^create_post/(?P<thread_id>[0-9]+)/$', views.create_post, name='create_post'),
url(r'^create_thread/$', views.create_thread, name='create_thread'),
]
Views
from django.shortcuts import render, redirect
from . import models
from . import forms
def index(request):
threads = models.Thread.objects.all()
thread_form = forms.Thread()
post_form = forms.Post()
return render(request, 'chan/index.html',{
'threads':threads,
'thread_form':thread_form,
'post_form':post_form,
})
def create_post(request, thread_id):
form = forms.Post(request.POST, request.FILES)
if form.is_valid():
post = Post(
text=request.POST['text'],
document=request.FILES['document'],
thread=models.Thread.get(pk=thread_id),
)
post.save()
return redirect('chan:index')
def create_thread(request):
form = forms.Thread(request.POST, request.FILES)
if form.is_valid():
thread = Thread(
text=request.POST['text'],
document=request.FILES['document']
)
thread.save()
return redirect('chan:index')
I've been on this for hours now checking for anything that I might've missed.

Honestly I have no idea what's you are trying to do. But when I look into that repo the hole thing is messed up. I have a few questions for you...
Why you don't have __init__.py? ( hole repo doesn't have, not good )
Best practise:
Place init.py file and call the module with from module import something
Why you don't have action attribute ?
You have url={% ...} but you should have action={%...}

Related

loading local files in django

I have a folder in c:\images, images here are updated by another app. Then I wanted a Django application to read those images on the admin site. The django applicationis sitting in c:\inetpub\wwwroot\myapp I have tried adding below lines in settings.py
CURRENT_PATH = os.path.abspath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(CURRENT_PATH, '../../images').replace('\\','/')
MEDIA_URL = 'images/'
I also tried including the whole path in django admin as below in admin.py
def img_field(self, obj):
return format_html('<img src="{}" width="500" height="500" />'.format("c:\images\phot1.png"))
If i put online image link it works fine as below:
def img_field(self, obj):
img = "https://www.thebalancesmb.com/thmb/5G9LJXyFzbTVS-Fj_32sHcgJ8lU=/3000x0/filters:no_upscale():max_bytes(150000):strip_icc():format(webp)/start-online-business-with-no-money-4128823-final-5b87fecd46e0fb00251bb95a.png"
return format_html('<img src="{}" width="500" height="500" />'.format(img))
How can i get around this?
I got it I just needed to add the below lines in urls.py
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#urls here
]
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
It is working fine.

why I have issues in importing views in the urls.py file?

from employee import views
does not work!...the server is giving a page not found (404) response
here is the project structure:
employee
migrations folder
....other files
views.py
hrdjango
__init__.py
settings.py
urls.py
I feel like the urls can't access my views
this is the views.py
from .models import Employee
# Create your views here.
def emp(request):
if request.method == "POST":
form = EmployeeForm(request.POST)
if form.is_valid():
try:
form.save()
return redirect('/show')
except:
pass
else:
form = EmployeeForm()
return render(request,'index.html',{'form':form})
def show(request):
employees = Employee.objects.all()
return render(request,"show.html",{'employees':employees})
def edit(request, id):
employee = Employee.objects.get(id=id)
return render(request,'edit.html', {'employee':employee})
def update(request, id):
employee = Employee.objects.get(id=id)
form = EmployeeForm(request.POST, instance = employee)
if form.is_valid():
form.save()
return redirect("/show")
from django.contrib import admin
from django.urls import path
from employee import views
urlpatterns = [
path('admin/', admin.site.urls),
path('emp', views.emp),
path('show',views.show),
path('edit/<int:id>', views.edit),
path('update/<int:id>', views.update),
path('delete/<int:id>', views.destroy),
]
urls.py
I am having unresolved import 'employee'message
Is this the project urls.py or the app-level urls.py? If this is your app level urls.py, then the import should be from . import views. If it is the project-level urls.py, then post up your file structure so we can see if the import structure is wrong.
I think the better solution would be to use separate urls.py file for separate apps and then include them to your root urls.
create a urls.py in your app.
in your root urls.py
from django.urls import path,include
urlpatterns = [
...,
...,
path('employee/', include('employee.urls')),
]

Django redirecting to a different view in another app

There are many similar questions to mine on Stack Overflow, but none which solve my problem.
I have a class-based view which accepts files, and once a valid file is found, I would like the website to redirect the user to a template inside a different app, passing in some parameters.
I've seen others put an extra path in 'urlpatterns' and get the view from there. But doing this only makes a GET signal on my command prompt, but not actually changing the web url.
views.py
from django.shortcuts import render, redirect # used to render templates
from django.http import JsonResponse
from django.views import View
from .forms import UploadForm
from .models import FileUpload
class UploadView(View):
def get(self, request):
files_list = FileUpload.objects.all()
return render(self.request, 'upload/upload.html', {'csv_files': files_list})
def post(self, request):
form = UploadForm(self.request.POST, self.request.FILES)
if form.is_valid():
csv_file = form.save()
data = {'is_valid': True,
'name': csv_file.file.name,
'url': csv_file.file.url,
'date': csv_file.uploaded_at}
# REDIRECT USER TO VIEW PASSING 'data' IN CONTEXT
return redirect('graph:chart', file_url=csv_file.file.url)
else:
data = {'is_valid': False}
return JsonResponse(data)
urls.py
from django.urls import path
from . import views
app_name = "upload"
urlpatterns = [
path('', views.UploadView.as_view(), name='drag_and_drop'),
]
urls.py (of other app)
from django.urls import path
from . import views
app_name = "graph"
urlpatterns = [
path('', views.page, name='chart'),
]
You can specify an app name and use exactly the redirect shortcut as you started:
https://docs.djangoproject.com/en/2.1/topics/http/urls/#naming-url-patterns
in the other app urls.py define app_name = 'other_app', and then use redirect('other_app:url_name', parameter1=p1, parameter2 = p2)
you can name easily your parameters either using path (Django >=2.0) or url (re_path for Django >=2.0), for instance:
from django.urls import path
from . import views
urlpatterns = [
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
]

How to properly setup custom handler404 in django?

According to the documentation this should be fairly simple: I just need to define handler404. Currently I am doing, in my top urls.py:
urlpatterns = [
...
]
handler404 = 'myapp.views.handle_page_not_found'
The application is installed. The corresponding view is just (for the time being I just want to redirect to the homepage in case of 404):
def handle_page_not_found(request):
return redirect('homepage')
But this has no effect: the standard (debug) 404 page is shown.
The documentation is a bit ambiguous:
where should handler404 be defined? The documentation says in the URLconf but, where exactly? I have several applications, each with a different urls.py. Can I put it in any of them? In the top URLconf? Why? Where is this documented?
what will be catched by this handler? Will it catch django.http.Http404, django.http.HttpResponseNotFound, django.http.HttpResponse (with status=404)?
As we discussed, your setup is correct, but in settings.py you should make DEBUG=False. It's more of a production feature and won't work in development environment(unless you have DEBUG=False in dev machine of course).
All the other answers were not up to date. Here's what worked for me in Django 3.1:
urls.py
from django.conf.urls import handler404, handler500, handler403, handler400
from your_app_name import views
handler404 = views.error_404
handler500 = views.error_500
views.py
def error_404(request, exception):
context = {}
return render(request,'admin/404.html', context)
def error_500(request):
context = {}
return render(request,'admin/500.html', context)
Note, you will have to edit this code to reflect your app name in the import statement in urls.py and the path to your html templates in views.py.
Debug should be False and add to view *args and **kwargs. Add to urls.py handler404 = 'view_404'
def view_404(request, *args, **kwargs):
return redirect('https://your-site/404')
If I didn't add args and kwargs server get 500.
To render 404 Error responses on a custom page, do the following:
In your project directory open settings.py and modify DEBUG as follows:
DEBUG = False
In the same directory create a file and name it views.py, insert the following code:
from django.shortcuts import render
def handler404(request, exception):
return render(request, 'shop/shop.html')
Finally open urls.py file which is in the same project directory and add the following code:
from django.contrib import admin
from . import views
handler404 = views.handler404
urlpatterns = [
path('admin/', admin.site.urls),
]

Django video in template, seems to detect media but not working

Please i have been working on this for a while but don't seem to find the problem. I am trying to get a video from the uploaded files to work on the template,but all i keep getting is a blank video, although when i view the page source or inspect the video element, it seems to be pointing to the right video, and all solutions i have tried to make this work proved abortive.
Below are my codes:
MY MODEL:
class Sermon(models.Model):
topic = models.CharField('Topic', max_length=50)
pub_date = models.DateField('Sermon Date')
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
last_edited = models.DateTimeField(auto_now_add=False, auto_now=True)
type = models.CharField('Type', max_length=50, choices=sermon_chioices)
audio = models.FileField(upload_to='audios', default="Not Available", blank=True, validators=[validate_audio_extension], null=True)
video = models.FileField(upload_to='videos', default="Not Available", blank=True)#can be changed if the video will recide in the system
outlines = models.FileField(upload_to="outlines", default="Not Available", blank=True,)
user = models.ForeignKey(User, verbose_name="User", editable=False)
class Meta:
ordering = ['-pub_date']
def __unicode__(self):
return self.topic
def get_absolute_url(self):
#return reverse('sermon_detail', kwargs={'pk': self.pk})
return reverse('sermon_detail', args=[str(self.id)])
MY VIEW:
class SermonDetails(DetailView):
model = Sermon
template_name = 'agonopa/sermon_details.html'
context_object_name = 'sermon'
def get_context_data(self, **kwargs):
context = super(SermonDetails, self).get_context_data(**kwargs)
#context['sermons'] = Sermon.objects.all()
return context
#Sunday Service List
class SundayServiceSermonList(ListView):
model = Sermon
template_name = 'agonopa/sermon.html'
context_object_name = 'sermon_list' #'ss_sermon_list'
queryset = Sermon.objects.filter(type__exact="SUNDAY SERVICE")
def get_context_data(self, **kwargs):
context = super(SundayServiceSermonList, self).get_context_data(**kwargs)
context['title'] = 'Sunday Service'
return context
MY TEMPLATE:
{% if sermon %}
<h3>{{ sermon.topic}}</h3>
{{sermon.outline}}
{{ sermon.pub_date}}
{% endif %}
<video loop class="embed-responsive-item thumbnails" controls>
<source src="{{ MEDIA_URL}}{{sermon.video.url}}" type="video/mp4">
</video>
MY MEDIA SETTINGS:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(BASE_DIR)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(PROJECT_DIR,'churchsite_static_root','media_root')
The Server returns things like this in the terminal:
[28/Nov/2015 11:38:10]"GET /agonopa/sermon/3/ HTTP/1.1" 200 377
[28/Nov/2015 11:38:10]"GET /media/videos/wowo_Boyz_5gQAbzG.mp4 HTTP/1.1" 404 2344
Thanks for your help in advance, and for further clarification on the question pls do let me know.
It should be noted, that i have tried many solutions from stakeoverflow, and several blogs but none seems to works, so i had to post it here.
It seems to me that your MEDIA_ROOT is way too high (as in no longer within your project). When I use the settings you use, I get a media root directory of ../../../churchsite_static_root/media_root/ relative to your settings.py file. I would expect churchsite_static_root to be one directory up from settings.py (or at the same level as manage.py).
Go into Django shell and check the media root path to see if it seems reasonable (and confirm that your files are actually there):
python manage.py shell
>>> from django.conf import settings
>>> settings.MEDIA_ROOT
Try the following in your settings.py and let me know if it helps:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, 'churchsite_static_root', 'media_root')
Be sure you have something like this in your site's urls.py if using python manage.py runserver:
# For Django>=1.8:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# For Django<1.8:
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
I simply imported settings, and then static, and also added the if Debug: to my urls.py, thus the program looked as below:
Urls.py:
from django.conf.urls import include, url, patterns
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from agonopa.views import SermonMonthArchiveView, SermonYearArchiveView
urlpatterns = [
# Examples:
# url(r'^$', 'churchsite.views.home', name='home'),
url(r'^$', 'agonopa.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^agonopa/', include('agonopa.urls')),
url(r'^grappelli/', include('grappelli.urls')),
url(r'^admin/', include(admin.site.urls)),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
That's all to it. Thanks to Mike Covington in all.
Also note, that the media settings, template and other files above didn't change for the whole stuff to work.