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
Related
I ran into a situation where I had developed a method called edit and passed both the profile and user forms into it when I wanted to modify a profile.
#login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user,data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile,data=request.POST,files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
return render(request,'users/edit.html',{'user_form':user_form,'profile_form':profile_form})
this is my views.py where i have written the logic
and coming to urls.py
path('edit/',views.edit,name='edit'),
and the edit.html code follows like this
{% extends 'users/base.html' %}
{% block body %}
<h2>Edit profile form</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit"/>
</form>
{% endblock %}
This is my models.py file
from django.db import models
from django.conf import settings
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
photo = models.ImageField(upload_to='users/%Y/%m/%d',blank=True)
def __str__(self):
return self.user.username
The main project urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('users/',include('users.urls'))
]
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
the output shows me like this
I am expecting a better solution to resolve this issue
This means that there is no Profile model instance for that user. You may want to use django postsave signals to create a Profile model instance for any user that has been created.
To test this, use the admin page to create a Profile model instance for that user and check if it still generates the error.
I hope this helps.
I have a django application that allow user to upload their image and then another dialog opens to collect user data related to them. After the dialog form has been submitted, I have added the javascript eventlistener to successfully submit the form with data and it redirects to the form's action attribute.
I wanna implement the same functionality, if user drop their image in the browser then dialog opens to collect user data, then do the same as above and redirect to the form's action attribute.
How can I achieve it?
Here is my code
#--urls.py
from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.index, name='index'),
path('success/', views.success_function, name='success page'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
#--views.py
def index(request):
form = userForm()
return render(request, 'polls/hello_world.html', {'form': form})
def success_function(request):
if request.method == 'POST':
form = userForm(request.POST, request.FILES)
user_files = request.FILES.getlist('django_image_field')
if form.is_valid():
images_data = []
for eachfile in user_files:
#handle_uploaded_file(eachfile)
file_path = file_upload(eachfile)
img_details = {'file_path': file_path, 'file_name': eachfile.name}
images_data.append(img_details)
return render(request, 'polls/success.html', {'data': images_data})
else:
print(form.errors)
return HttpResponse("Not valid form")
else:
return HttpResponse("Not a valid method")
--under forms.py
class NameForm(forms.Form):
your_name = forms.CharField(required=False, label='Your name', max_length=100)
django_image_field = forms.ImageField(required=True,
label="",
widget=forms.ClearableFileInput(attrs={
'multiple': True,
'id':'file-input'
}))
--#inside index
<form enctype="multipart/form-data" action="{% url 'success' %}" id="myform" method="POST">
{% csrf_token %}
{{ form.django_image_field }}
<dialog id="user_dialog">
<form method="dialog" id="more_details">
</h6>
<p>Enter Name: </p>
{{ form.your_name.label_tag }}
{{ form.your_name }}
<button id="submit_btn" type="submit">Submit</button>
</form>
</dialog>
</form>
I have a simple app that uses an ImageField to upload & store a photo. I'm running the app local. The form displays as expected, and allows me to browse and select a jpg file. It then shows the selected filename next to the "Choose File" button as expected. When I submit the form, it saves the model fields 'name' and updates 'keywords' but it does not save the file or add the filename to the db. No errors are generated. Browsing the db, I see the newly added record, but the 'photo' column is empty. Any help appreciated.
settings.py:
MEDIA_ROOT = '/Users/charlesmays/dev/ents/ents/enrich/'
models.py:
class Enrichment(models.Model):
name = models.CharField( max_length=255, unique=True)
keywords = models.ManyToManyField(KeyWord, blank=True)
photo = models.ImageField(upload_to='enrichments/', null=True, blank=True)
views.py:
def EnrichmentUploadView(request):
if request.method == 'POST':
form = CreateEnrichmentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('index'))
else:
return render(request, 'createEnrichment.html', {'form':form})
else:
form = CreateEnrichmentForm()
return render(request, 'createEnrichment.html', {'form':form})
forms.py:
class CreateEnrichmentForm(forms.ModelForm):
class Meta:
model = Enrichment
fields = ('name', 'photo', 'keywords')
enctype="multipart/form-data"
template:
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
Change all these, then it should work..
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
-------
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py
photo = models.ImageField(upload_to="enrichments/", default="")
And your template form
<form action="" id="" method="" enctype="multipart/form-data">
------
</form>
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)
I tried to make simple request form. And I need to redirect user to "thank you" page after successful form sent. But after user hit "send" button - nothing happens. Just reload form page without form cleaning also.
Form is on "call" page, redirect needs "confirm" page...
So, task is: user fill the form on page "call" and after hitting "send" button, goes to "confirm" page.
My model:
# -*- coding: utf-8 -*-
from django.db import models
from django.forms import ModelForm
# Create your models here.
class Join(models.Model):
class Meta():
db_table = 'expert_request'
user_expert = models.CharField(max_length=100)
user_name = models.CharField(max_length=100)
user_cost = models.CharField(max_length=100)
user_email = models.EmailField()
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self):
return self.user_email
my "forms.py":
from django import forms
from userform.models import Join
class JoinForm(forms.ModelForm):
class Meta:
model = Join
This is my "views.py":
from django.shortcuts import render
from django.shortcuts import HttpResponseRedirect, Http404
# Create your views here.
from userform.forms import JoinForm
from userform.models import Join
def userform(request):
form = JoinForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
new_join.save()
HttpResponseRedirect('/confirm/')
context = {"form": form}
template = "userform.html"
return render(request, template, context)
def confirm(request):
return render(request, 'confirm.html')
This is my URL's:
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
(r'^tinymce/', include('tinymce.urls')),
url(r'^$', 'expert.views.index', name='index'),
url(r'^(\d+)/?$', 'expert.views.index'),
url(r'^call/$', 'userform.views.userform', name='call'),
url(r'^confirm/$', 'userform.views.confirm', name='confirm'),
)
My template "userform.html":
{% load staticfiles %}
<form style="position:relative" method="POST" action="">{% csrf_token %}
{{ form.user_expert }}
<p style="position:absolute; top:50px; left:20px; color:#FF0000;">{{ form.user_expert.errors.as_text }}</p>
{{ form.user_name }}
<p style="position:absolute; top:182px; left:20px; color:#FF0000;">{{ form.user_name.errors.as_text }}</p>
{{ form.user_cost }}
<p style="position:absolute; top:50px; left:380px; color:#FF0000;">{{ form.user_cost.errors.as_text }}</p>
{{ form.user_email }}
<p style="position:absolute; top:182px; left:380px; color:#FF0000;">{{ form.user_email.errors.as_text }}</p>
<button type="submit">Send</button>
<div class="clear"></div>
</form>
Maybe you forgot the return statement in userform view function? Fix its beginning like this:
def userform(request):
form = JoinForm(request.POST or None)
if form.is_valid():
new_join = form.save(commit=False)
new_join.save()
return HttpResponseRedirect('/confirm/')