I am working on a twitter clone app and i want users to have a default profile photo when they sign up and login. I have set up the model to upload the default image but for some reason its not displaying.
models.py
from django.db import models
from django.contrib.auth.models import User
#import pylibjpeg_libjpeg
from PIL import Image
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to='profile_pics', default='default.png')
def __str__(self):
return f'{self.user.username} Profile'
#property
def followers(self):
return Follow.objects.filter(follow_user=self.user).count()
#property
def following(self):
return Follow.objects.filter(user=self.user).count()
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
super().save()
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
views.py
#login_required
def profile(request):
if request.method == 'POST':
uform = UserUpdateForm(request.POST, instance=request.user)
pform = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if uform.is_valid() and pform.is_valid():
uform.save()
pform.save()
messages.success(request, f'Account updated.')
return redirect('profile')
else:
uform = UserUpdateForm(instance=request.user)
pform = ProfileUpdateForm(instance=request.user.profile)
return render(request, 'Users/profile.html', {'uform': uform, 'pform': pform})
settings file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
html file
<article class="media content-section" style="height:140px; width:100%">
{% if user_profile != None %}
<div class="mt-2 d-flex full-width align-items-center">
<img class="rounded-circle mr-3 img-fluid" style="width:90px; height:90px" src="{{ user_profile.profile.image.url }}">
<div>
<h4 style="text-align: left" class="white-important">
{{ user_profile.username}}
</h4>
<h6 style="text-align:left" class="email-profile">
{{ user.email }}
</h6>
</div>
</div>
{% else %}
<div class="mt-2 d-flex full-width align-items-center">
<img class="rounded-circle mr-3" style="width:90px; height:90px;" src="{{ user.profile.image.url }}" alt="profile picture">
<div>
<h4 style="text-align: left" class="white-important">
{{ user.username }}
</h4>
<h6 style="text-align:left" class="email-profile">
{{ user.email }}
</h6>
</div>
</div>
{% endif %}
my project's urls.py file
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
from django.conf import settings
from django.conf.urls.static import static
from Users import views as users_views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', auth_views.LoginView.as_view(template_name='Users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='Users/logout.html'), name='logout'),
path('password-reset/', auth_views.PasswordResetView.as_view(template_name='Users/password_reset.html'),name='password-reset'),
path('password-reset/done', auth_views.PasswordResetDoneView.as_view(template_name='Users/password_reset_done.html'), name='password-reset-done'),
path('password-reset/confirm/<uid64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='Users/password_reset_confirm.html'), name='password-reset-done'),
path('register/', users_views.register, name='register-users'),
path('profile/', users_views.profile, name='profile'),
path('search/', users_views.SearchView, name='search'),
path('', include("Blog.urls")),
]
if settings.DEBUG is True:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
here's the screenshot of the output after the user logs in
It seems like you are not serving the media files locally. Check the documentation here
inspect the image on your browser and see what is being rendered. also, try adding a trailing slash to the media_root such that it is MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
In views.py check the indentation of pform.save() ...
if still not working follow/check these steps :
settings.py:
STATIC_DIR = os.path.join(BASE_DIR,"static")
MEDIA_DIR = os.path.join(BASE_DIR, 'media')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
STATIC_DIR,
]
#MEDIA
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
LOGIN_URL = 'user_login'
create a folder named media with a subfolder profile_pics in your base directory (the folder where you have your manage.py file)
also check this similar code :
models.py :
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class user_profile(models.Model):
#using default User model by linking
user = models.OneToOneField(User, on_delete=models.CASCADE)
#additional fields
website = models.URLField(blank=True)
profile_picture = models.ImageField(upload_to='profile_pictures' , blank = True )
bio = models.CharField(blank=True, max_length=300)
def __str__(self):
return self.user.username
forms.py:
from django import forms
from django.contrib.auth.models import User
from .models import user_profile
class User_form(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ("username", "email" , "password")
class user_profile_form(forms.ModelForm):
class Meta:
model = user_profile
fields = ("profile_picture", "website" , "bio")
views.py :
def signup(request):
registered = False
if request.method == "POST":
user_form = User_form(data=request.POST)
user_profileform = user_profile_form(data=request.POST)
if(user_form.is_valid() and user_profileform.is_valid()):
user = user_form.save()
user.set_password(user.password)
user.save()
profile = user_profileform.save(commit=False)
profile.user = user
if 'profile_picture' in request.FILES:
profile.profile_picture = request.FILES['profile_picture']
profile.save()
registered = True
else:
print(user_form.errors, user_profileform.errors)
else:
user_form = User_form()
user_profileform = user_profile_form()
return render(request, "registration/signup.html", {'user_form': user_form , 'user_profileform' : user_profileform, 'registered' : registered } )
Also make sure your template form has the "multipart/form-data":
signup.html :
<form enctype="multipart/form-data" method="POST">
<div class="container sign-form">
{% csrf_token %}
{{ user_form |as_bootstrap }}
{{ user_profileform |as_bootstrap }}
<!-- {{ user_profileform.as_p }} -->
<input type="submit" class = “btn btn-default” name="submit" value="submit">
also check if you are rendering the image in the template properly . something like this ,
<div class="container">
<img src="media/{{[context_object_name].image}}" class="imgbar" id="img">
</div>
even now not solved, open the browser console and let know what is the error displayed
edit :
add this[+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)] to your urls.py,
urls.py:
from django.urls import path,include
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'homepage'
urlpatterns = [
path('', views.home , name = "home"),
path('contact', views.contact , name = "contact"),
path('about', views.about , name = "about"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Related
I tried to upload image from the admin side in production but it doesn't shows up or stores in static/images but it used to work while working in local.
However my static images are loaded and also those I've saved in development are also showing up but while adding new images it doesn't get added to static files.
My model:
class Gallery(models.Model):
title = models.CharField(max_length=150)
image = models.ImageField(upload_to='images/',null=True,default="avatar.svg")
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Urls.py
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('base.urls'))
]
urlpatterns +=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
Gallery .html
{% for gallery in gallerys %}
<!-- ITEM 1 -->
<div class="col-xs-6 col-md-3">
<div class="box-gallery">
<a href="{{gallery.image.url}}" title="Gallery #1">
<img src="{{gallery.image.url}}" alt="" class="img-fluid" />
<div class="project-info">
<div class="project-icon">
<span class="fa fa-search"></span>
</div>
</div>
</a>
</div>
</div>
{% endfor %}
Settings.py
here i've uploaded only the required ones
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_URL = '/static/'
AUTH_USER_MODEL = 'base.NewUser'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static/")
MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "/static/images")
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
views.py
def gallery(request):
gallerys = Gallery.objects.all()
context = {'gallerys':gallerys}
return render(request, 'base/gallery.html',context)
am i missing something here?
Thanks in advance
The way to store images in static folder.
Do this:
views.py:
def gallery(request):
if request.method == 'POST':
form = YourForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['image'])
model_instance = form.save()
model_instance.save()
else:
form = YourForm()
gallerys = Gallery.objects.all()
context = {'gallerys':gallerys}
return render(request, 'base/gallery.html',context)
def handle_uploaded_file(f):
with open('static/images/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
settings.py:
STATIC_URL = 'static/'
STATIC_ROOT=os.path.join(BASE_DIR,'static')
urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('base.urls'))
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
This is the way that you can store static files.
I hope this may be get you
I'm new to Django, and I encounter this problem with images that I can't solve... The path is like this: Django-Project, Profiles, static, media, profileIMG.
Here is my model.
from django.db import models
from accounts.models import NewUser
class UserProfile(models.Model):
user = models.OneToOneField(NewUser, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='Untitled.png', upload_to='profileIMG')
def __str__(self):
return self.user.username
settings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
urls.py
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('accounts.urls')),
path('', include('profiles.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
form.py
from django.forms import ModelForm
from .models import UserProfile
class ProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = '__all__'
exclude = ['user']
view.py function
#login_required(login_url='login_user')
def profiles(request):
indexID = request.user
form = ProfileForm(instance=indexID)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=indexID)
if form.is_valid():
messages.success(request, ("The file is valid"))
form.save()
else:
messages.success(request, ("Invalid File."))
context = {'form': form}
return render(request, "profiles/profiles.html", context)
And my template profiles.html.
{% load static %}
<div class="main">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<img class="profile-pic" src="{{ request.user.UserProfile.profile_pic.url
}}"/>
<p>This is profile page </p>
<span>Hello, {{request.user}} </span>
<p>{{ form }}</p>
<input class="imgBTN" type="submit" name="imgBTN">
<span>Logout</span>
</form>
</div>
I'm trying to select an image dynamically, not just adding the name of the picture.
Does anyone know how to fix this, please?
in your views all of method is post, nothing get method to get data from database
try add profile = UserProfile.object.get()
and then add context 'profile':profile
so the full view.py like this
#login_required(login_url='login_user')
def profiles(request):
indexID = request.user
profile = UserProfile.object.get(user=indexID)
form = ProfileForm(instance=indexID)
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=indexID)
if form.is_valid():
messages.success(request, ("The file is valid"))
form.save()
else:
messages.success(request, ("Invalid File."))
context = {'form': form, 'profile':profile}
return render(request, "profiles/profiles.html", context)
good luck and keep coding
I was working on a django project. I made a userprofiles app to manage(create, update) user's profile in my website, but it is not working properly. I am getting 'This field is required' &
'no file chosen' while making profile as a user and if I do blank=True in models profile_picture user pictures are not saving in the media url.
I have tried so many tips from stackoverflow but they are not working.
here is my code:
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))
# models.py
from django.db import models
from django.contrib.auth import get_user_model
import uuid
class UserProfile(models.Model):
author = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='images/')
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
bio = models.TextField(blank=True)
occupation = models.CharField(max_length=100)
hobbies = models.TextField(blank=True)
date_of_birth = models.TimeField()
def __str__(self):
return self.author.username + ("'s profile")
# views.py
from django.views.generic import CreateView
from .forms import CustomUserCreationForm
from django.urls import reverse_lazy
class SignUpView(CreateView):
form_class = CustomUserCreationForm
template_name = "registration/signup.html"
success_url = reverse_lazy("profile_create")
# project-level urls.py
from django.contrib import admin
from django.conf import settings
from django.urls import path, include
from django.conf.urls.static import static
from django.views.generic.base import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path("accounts/", include("accounts.urls")),
path("accounts/", include("django.contrib.auth.urls")),
path("profile/", include("userprofiles.urls")),
path("", TemplateView.as_view(template_name="home.html"), name="home"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# app-level urls.py
from django.urls import path
from .views import ProfileCreateView
urlpatterns = [
path("create/", ProfileCreateView.as_view(), name="profile_create")
]
# profile_create.html
{% extends 'base.html' %}
{% block title %}Create Your Profile{% endblock title %}
{% block content %}
<h2>Create Your Profile</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create my profile</button>
</form>
{% endblock content %}
tell me what is the problem with it, I am stucked out of it, Thank you
I believe you missed enctype in html form,
enctype="multipart/form-data"
from docs,
Note that request.FILES will only contain data if the request method
was POST, at least one file field was actually posted, and the
that posted the request has the attribute
enctype="multipart/form-data". Otherwise, request.FILES will be empty.
HTML form should be,
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create my profile</button>
</form>
Intro
I am following the Django tutorial. In contrast to it I have two databases - MySql and Cassandra. Therefore, I need to use also the Cassandra models which contain the UUID types. Thee UUID has the form of 32 alphanumeric characters and four hyphens (8-4-4-12). Therefore, I have quite complicated regex in my urls.py:
^([A-Fa-f0-9]{8}))(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}
Problem
In the polls/templates/polls/detail.html teplate is the following line:
<form action="{% url 'polls:vote' question.question_id %}" method="post">
The UUID type of question.question_id is then translated to the:
/polls/UUID('47de663a-57f2-4ca1-9ad9-81df9ae25973')/
instead of
/polls/47de663a-57f2-4ca1-9ad9-81df9ae25973/
Therefore, I've got the error message:
Reverse for 'vote' with arguments
'(UUID('47de663a-57f2-4ca1-9ad9-81df9ae25973'),)' and keyword
arguments '{}' not found. 1 pattern(s)
tried:[u'polls/(?P^([A-Fa-f0-9]{8})(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12})/vote/$'
Question
How to handle the UUID type?
I suppose I can not use the str(question.question_id) function in the {% url} tag.
Source
Root urls - mysite/urls.py:
from django.conf.urls import url
from . import views
app_name= 'polls'
urlpatterns = [
#ex: /polls/
url(r'^$',views.index, name='index'),
#ex: /polls/uuid
url(r'^(?P<question_id>^([A-Fa-f0-9]{8})(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12})/$', views.detail, name='detail'),
#ex: /polls/uuid/results/
url(r'^(?P<question_id>^([A-Fa-f0-9]{8})(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12})/results/$', views.results, name='results'),
#ex: /polls/uuid/vote
url(r'^(?P<question_id>^([A-Fa-f0-9]{8})(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12})/vote/$', views.vote, name='vote'),
]
Polls app polls/urls.py:
from django.conf.urls import url
from . import views
app_name= 'polls'
urlpatterns = [
url(r'^$',views.index, name='index'),
#ex: polls/5/results/
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
#ex: /polls/5/volte
url(r'^(?P<question_id>(^([A-Fa-f0-9]{8}))(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12})/vote/$', views.vote, name='vote'),
#ex: polls/5/
url(r'^(?P<question_id>[^/]+)/$',views.detail, name='detail'),
]
polls/views.py:
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render, get_object_or_404
from .models import Question, Choice
from django.shortcuts import get_object_or_404, render
def index(request):
#latest_question_list = Question.objects.order_by('-pub_date')[5:]
latest_question_list = Question.objects()
context = {
'latest_question_list': latest_question_list,
}
return render(request, 'polls/index.html', context)
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question':question})
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = get_object_or_404(Choice, pk=question_id)
#selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(
reverse('polls:results', args=(question.question_id,))
)
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
polls/templates/polls/detail.html:
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.question_id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
polls/Models.py:
from django.db import models
# Create your models here
import uuid
from cassandra.cqlengine import columns
from cassandra.cqlengine import models
from django_cassandra_engine.models import DjangoCassandraModel
class User(models.Model):
username = columns.Text(primary_key=True)
password = columns.Text()
email = columns.Text()
fullname = columns.Text()
is_staff = columns.Boolean(default=False)
class ExampleModel(DjangoCassandraModel):
example_id = columns.UUID(primary_key=True, default=uuid.uuid4)
example_type = columns.Integer(index=True)
created_at = columns.DateTime()
description = columns.Text(required=False)
class Question(DjangoCassandraModel):
def __str__(self):
return self.question_text
question_id = columns.UUID(primary_key=True)
question_text = columns.Text()
pub_date = columns.TimeUUID()
class Choice(DjangoCassandraModel):
def __str__(self):
return self.choise_text
question = columns.UUID(primary_key=True)
choice_text = columns.Text()
votes = columns.Integer(index=True,default=0)
Your question_id regex is wrong. If you're using uuid4 as you appear to be (and assuming you don't want capitals to validate because python's uuid.uuid4() produces lowercase when rendered as a string), the regex for the question_id captured group is:
(?P<question_id>[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12})
Edit for Django 2.0:
Django now has path converters, so you don't need the uuid4 regex anymore. Here's an example:
from django.urls import path
urlpatterns = [
path('questions/<uuid:question_id>/', MyView.as_view()),
]
I am trying to build a simple landing page in Django that will allow users to sign up for an email newsletter. I am using this cookie cutter template - https://github.com/Parbhat/cookiecutter-django-foundation - because it integrates Foundation 6 from the jump.
The challenge is that the form fields are not showing in the template. Any help would be appreciated.
My models.py is:
class Subscribe(models.Model):
email = models.EmailField()
subscription_status = models.BooleanField(default=True)
create_date = models.DateTimeField(auto_now_add = True, auto_now = False)
update_date = models.DateTimeField(auto_now_add = False, auto_now = True)
def __unicode__(self):
return self.email
My forms.py is:
from django import forms
from .models import Subscribe
class SubscribeForm(forms.ModelForm):
class Meta:
model = Subscribe
fields = ('email',)
My views.py is:
from django.shortcuts import render
from subscribers.forms import EmailForm, SubscribeForm
from .models import Subscribe
def home(request):
form = SubscribeForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
#we might need to do something here.
email = form.cleaned_data['email']
new_join_old, created = Subscribe.objects.get_or_create(email=email)
#new_join.save()
context = {"form": form}
template = "pages/home.html"
return render(request, template, context)
And my template is:
{% extends "base.html" %}
{% load foundation_formtags %}
{% block content %}
<section class="hero">
<!-- HERO SECTION -->
<div class="homebox">
<div class="wrap">
<p>Lorem Ipsum</p>
<form class="form" method="post" action=""> {% csrf_token %}
{{ form|as_foundation }}
<input type='submit' value='Subscribe' class='btn' />
</form>
</div>
</div>
</section>
My urls.py is:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from django.conf.urls import url
from . import views
from subscribes.views import home
urlpatterns = [
url(r'^$', home, name='home'),
]
Thanks!