Django blog not displaying images - blogs

I followed this tutorial on adding images to my django blog (tutorial link: https://www.youtube.com/watch?v=ygzGr51dbsY&list=PLCC34OHNcOtr025c1kHSPrnP18YPB-NFi&index=26)
But when I post a blog post the image doesn't get displayed
But the image gets saved in a folder
But when I go to the admin panel and click on the post I see this
when I click on the currently location I get this
This is my settings.py
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
# BASE_DIR = Path(__file__).resolve().parent.parent
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
'NAME': 'db.sqlite3',
}
}
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_FILE_DIRS = (
os.path.join(BASE_DIR, 'static')
)
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
But that guys BASE_DIR variable was different than mine.(I think cause he is using django 2 and I am using django 3)
So I hashed mine out and changed the BASE_DIR variable and removed it from the DATABASES dictionary.
My urls.py file
urlpatterns = [
path('register/', UserRegisterView.as_view(), name='register'),
path('edit_profile/', UserEditView.as_view(), name='edit_profile'),
# path('password/', auth_views.PasswordChangeView.as_view(template_name='registration/change-password.html')),
path('password/', PasswordsChangeView.as_view(template_name='registration/change-password.html'), name='change-password'),
path('password_success/', password_success, name='password-success')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My add_post.html file
<head>
<title>Add Post...</title>
</head>
<h1>Add Blog Post...</h1>
<br/><br/>
<div class="form-group">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<button class="btn btn-secondary">Post</button>
</form>
</div>
My detail_view.html file
<h1>{{ post.title }}</h1>
<small>By: {{ post.author.first_name }}
{{ post.author.last_name }} -
{{ post.post_date }}
{% if user.is_superuser or user.is_staff and post.author.id == user.id %}
(Edit) (Delete) <br/>
{% endif %}
<hr>
</small>
<img src="{{ post.header_image.url }}">
If I forgot to display the file please tell me.
Thank you.

I fond the problem. I need to add the + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to my main urls.py

Related

NoReverseMatch at / when trying to add href in Django

I have a list of items and I am trying to add a link to the item's title to direct the user to the item's own page. However, I am getting Reverse for 'listing' with arguments '('',)' not found. 1 pattern(s) tried: ['listing/(?P<listing_id>[0-9]+)\\Z'] error and I couldn't figure out what I did wrong.
The error is in line<h2>{{auction.title}}</h2> of index.html
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("create", views.create_listing, name="create"),
path("listing/<int:listing_id>", views.listing, name = "listing"),
]
views.py:
def listing(request,listing_id):
listing = AuctionItem.objects.get(id = listing_id)
return render(request, "auctions/listing.html",{
"listing":listing
})
index.html:
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Active Listings</h2>
{% for auction in auctions %}
<div class = "frame">
<img src="{{auction.image}}" style= "width: 30vw;">
<h2>{{auction.title}}</h2>
<div id="text"><strong>Price:</strong> ${{auction.price}}</div>
<div id="text"><strong>Description:</strong> {{auction.description}}</div>
<div id="text"><strong>Category:</strong> {{auction.category}}</div><br>
<div id="date">Created {{auction.date}}</div>
</div>
{% empty %}
<li>No item.</li>
{% endfor %}
{% endblock %}
The object is named auction in the context when rendering, so:
<h2>{{auction.title}}</h2>
or perhaps better to use the .pk:
<h2>{{auction.title}}</h2>

Django HTML button on-click invoke backend function

im trying to add to my html a button that appears only on certain events, that works for me but i want to add a onclick script/function that will invoke a backend view.py function that deletes the specific room on click, the room model is : owner(fk), name, slug.
and the user model is : username password1 password2.
i just need to know how to invoke an onclick event that will call the backend function in my views.
rooms.html
{% extends 'core/base.html' %}
{% block title %} Rooms | {% endblock %}
{% block content %}
<div class="main">
<h1>Rooms</h1>
</div>
<div class="rooms-container">
{% for room in rooms %}
<div class="room">
<div class="room-info">
<h1 class="room-title">{{ room.name }}</h1>
Join Room
{% if request.user == room.owner %}
<button class="room-delete" id="roomDelete">Delete Room</button>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<!-- todo: add delete room button functionality. -->
{% endblock %} ```
views.py
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
from django.contrib import messages
from .models import Room, Message
#login_required
def rooms(request):
if request.method == 'POST':
room_owner = request.user
room_name = request.POST['room-name']
if not Room.objects.filter(slug = room_name).exists():
if room_name == '' or room_name.isspace() or room_name.startswith(' '):
messages.info(request, 'Invalid room name, spaces-only or string that starts with spaces is invalid.')
else:
new_room = Room(owner = room_owner,name = room_name,slug = room_name)
new_room.save()
else:
messages.info(request, 'That room already exists!, try a different name.')
rooms = Room.objects.all()
return render(request, 'room/rooms.html', {'rooms': rooms})
#login_required
def room(request, slug):
room = Room.objects.get(slug=slug)
messages = Message.objects.filter(room=room)[0:25]
return render(request, 'room/room.html', {'room': room, 'messages': messages})
#csrf_exempt
def delete_room(request): ## <<------ invoke this from html call.
print("hey")
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.rooms, name='rooms'),
path('<slug:slug>/', views.room, name='room'),
path('', views.delete_room, name='delete_room'),
]
now i have more 2 urls.py, the project has 3 folders, 1 main (livechatapp) with settings and all, one for core htmls (core) and one for rooms html (room)
core/urls
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path('', views.frontpage, name='frontpage'),
path('signup/', views.signup, name='signup'),
path('login/', auth_views.LoginView.as_view(template_name='core/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
and finally
livechatapp/urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('core.urls')),
path('rooms/', include('room.urls')),
path('admin/', admin.site.urls),
]
and this is the projects overview folders and files :
this is the project
IF you want do it in standard html:
% extends 'core/base.html' %}
{% block title %} Rooms | {% endblock %}
{% block content %}
<div class="main">
<h1>Rooms</h1>
</div>
<div class="rooms-container">
{% for room in rooms %}
<div class="room">
<div class="room-info">
<h1 class="room-title">{{ room.name }}</h1>
Join Room
{% if request.user == room.owner %}
<form method="POST" action="{% url 'delete_room' room.slug %}>
<button type="submit" class="room-delete">Delete Room</button></form>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<!-- todo: add delete room button functionality. -->
{% endblock %} ```
urls:
urlpatterns = [
path('', views.rooms, name='rooms'),
path('<slug:slug>/', views.room, name='room'),
path('delete/<slug:slug>/', views.delete_room, name='delete_room'),
]
views:
#csrf_exempt
def delete_room(request,slug):
if request.method == 'POST':
try:
room = Room.objects.get(slug=slug, owner=request.user)
room.delete()
except ObjectDoesNotExist:
print('there is no room with this slug or you are not owner')
return redirect('rooms')
i advice to use csrf. allways try to use POST when manipulatind data in db.
If you want to work it without redirect you need to think of ajax call or maby htmx

Django - Success Message Mixin Does not work on Login

I'm trying to display a success message on login using the SuccessMessageMixin but the message is not displayed. Is there any reason why this would happen?
settings.py
LOGIN_REDIRECT_URL = 'home'
LOGIN_URL = 'login'
LOGOUT_REDIRECT_URL = 'home'
LOGOUT_URL = 'logout'
urls.py
from .views import HomeView, LoginFormView
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', HomeView.as_view(), name = 'home'),
path('login/', LoginFormView.as_view(), name = 'login'),
]
views.py
class HomeView(FormView):
template_name = 'home.html'
class LoginFormView(auth_views.LoginView, SuccessMessageMixin):
template_name = 'login.html'
success_url = 'home/'
success_message = "You were successfully logged in."
login.html
<h4>Login to your Account:</h4>
<div>
<form action "" method = "POST">
{% csrf_token %}
{{form}}
<button type = "submit">Login</button>
</form>
</div>
home.html
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
The SuccessMessageMixin needs to be first (or atleast before the generic view) in the order of inheritance, i.e. it should be LoginFormView(SuccessMessageMixin, auth_views.LoginView) instead of LoginFormView(auth_views.LoginView, SuccessMessageMixin):
class LoginFormView(SuccessMessageMixin, auth_views.LoginView):
template_name = 'login.html'
success_url = 'home/'
success_message = "You were successfully logged in."

Exception Type: NoReverseMatch - Django

after researching for hours I cannot get rid of this error, I hope someone can help me.
Models:
class Puja(models.Model):
seller = models.OneToOneField(Seller, on_delete=models.CASCADE)
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True,null=True)
title = models.CharField(max_length=100)
video = models.FileField(blank=True)
photo = models.ImageField(blank=True)
published_date = models.DateTimeField("Published: ",default=timezone.now())
bidding_end = models.DateTimeField()
starting_price = models.IntegerField(default=1)
#slug = models.SlugField(null=True)
def __str__(self):
return str(self.title)
#def get_absolute_url(self):
# return reverse('bidding_list_detail', args=[str(self.id)])
#slug time
def get_absolute_url(self):
return reverse('bidding_list_detail',args={'id': self.id})
Views:
class bidding_list(ListView):
model = Puja
template_name = 'bidding_templates/bidding_list.html'
"""return render(request= request,
template_name='bidding_templates/bidding_list.html',
context = {"Pujas": Puja.objects.all})"""
class bidding_list_detail(DetailView):
model = Puja
template_name = 'bidding_templates/bidding_list_detail.html'
urls:
path('admin/', admin.site.urls),
path("bidding_list/", bidding_list.as_view(), name="bidding_list"),
path('<int:pk>', bidding_list_detail.as_view(), name='bidding_list_detail'),
admin:
class PujaAdmin(admin.ModelAdmin):
list_display = ('seller','title','video','photo','published_date','bidding_end','starting_price')
admin.site.register(Puja,PujaAdmin)
template 1:
{% extends 'header.html' %}
{% block content %}
<h1>Pujas</h1>
{% for Puja in object_list %} <!--object_list-->
<ul>
<li> {{ Puja.title }} </li>
</ul>
{% endfor %}
{% endblock %}
template 2:
{% extends 'header.html' %}
{% block content %}
<div>
<h2>{{ object.title }}</h2>
<p>{{ object.seller }}</p>
</div>
{% endblock %}
Note that, whenever I remove <a href="{{ Puja.get_absolute_url }}"> from the first template, the objects "puja" in the model get properly displayed on the template, but I cannot access them. They normally exist on the admin panel, but not displayed on the website directly.
Thank you very much on advance and stay healthy.
edit 1: Here is the urls.py directly from the app created by django. To be more specific, I created after the project a new app called "main" in which I programmed all the project, including all the code on this question except the edit.
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
#from django.config import settings
#from django.config.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('main.urls')),
#path('', include('model.urls')),
#path('', include('blog.urls')),
#path('', include('photo.urls')),
#path('', include('video.urls')),
] # +static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I guess the problem is this line - return reverse('bidding_list_detail',args={'id': self.id}), you are passing id as a string but trying to match with int in url.Try following return reverse ('bidding_list_detail',args=[self.id])

Django not getting images that are uploaded to sqlite

Images are not coming into template.
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
html
{% for question in question_list %}
<img src= "{{question.image}}">
models.py
class NewQuestion(models.Model):
category = models.ForeignKey(Category)
question_text = models.CharField(max_length = 200, unique = True, null = False)
image = models.ImageField(upload_to='images')
def __unicode__(self):
return self.question_text
To render a photo from an ImageField in Django's templating language, the following syntax is required:
{{ image.url }}
In your case:
{% for question in question_list %}
<img src= "{{ question.image.url }}">
{% endfor %}
Try this:
{% for question in question_list %}
<img src= "{{question.image.url}}">
{% endfor %}
Reference to docs:
A read-only property to access the file’s relative URL by calling the url() method of the underlying Storage class.
Update:
Adding this to your urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)