I'm on chapter 9 in Tango With Django - creating user authentication. In the registration page I have the option of uploading a picture. In my admin file everything looks good after I register myself. I show up in the User Profiles, and it even shows the image I uploaded:
Picture: Currently: profile_images/earth.jpeg Clear. However when I click on that picture this is the error message I get:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/admin/rango/userprofile/1/change/profile_images/earth.jpeg/change/
Raised by: django.contrib.admin.options.change_view
user profile object with primary key u'1/change/profile_images/earth.jpeg' does not exist.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
models.py:
from __future__ import unicode_literals
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Category, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=128)
url = models.URLField()
views = models.IntegerField(default=0)
def __str__(self):
return self.title
class UserProfile(models.Model):
user = models.OneToOneField(User)
website = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_images', blank=True)
def __str__(self):
return self.user.username
views.py - only the register():
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
profile.save()
registered = True
else:
print user_form.errors, profile_form.errors
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request, 'rango/register.html',
{'user_form': user_form,
'profile_form': profile_form,
'registered': registered}
)
finally, my register.html file:
{% extends 'rango/base.html' %}
{% load staticfiles %}
{% block title_block %}
Register
{% endblock %}
{% block body_block %}
<h1>Register with Rango</h1>
{% if registered %}
Rango says: <strong>thank you for registering!</strong>
Return to the homepage<br/>
{% else %}
Rango says: <strong>register here!</strong>
Click here to go to the homepage<br/>
<form id="user_form" method="post" action="/rango/register/" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
{% endblock %}
user profile object with primary key u'1/change/profile_images/earth.jpeg' does not exist.
It looks like one of your URL patterns may be off; it probably just wants to capture that 1 to use as the PK for a lookup, but instead is capturing 1/change/profile_images/earth.jpeg.
Related
I have created a model and a form, both are working correctly, and I have added data to the database using the admin module
models.py
class Client(models.Model):
firstname = models.CharField(blank=True, max_length=30)
lastname = models.CharField(blank=True, max_length=15)
company = models.ForeignKey(Company, on_delete=models.CASCADE, default="company")
position = models.CharField(blank=True, max_length=15)
country = CountryField(blank_label='(select country)')
email = models.EmailField(blank=True, max_length=100, default="this_is#n_example.com")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
phone = PhoneField(default="(XX)-XXX-XXX")
def __str__(self):
return f'{self.firstname}'
forms.py
class ClientForm(forms.ModelForm):
class Meta:
model = Client
fields = ('firstname', 'lastname',"position",'country','email','phone')
views.py
#login_required
def add_client(request):
if request.method == "POST":
client_form = ClientForm(instance=request.user, data=request.POST)
if client_form.is_valid():
client_form.save()
messages.success(request, 'You have successfully added a client')
else:
messages.success(request, "Error Updating your form")
else:
client_form = ClientForm(instance=request.user)
return render(request,
"account/add_client.html",
{'client_form':client_form})
add_client.html
{% extends "base.html" %}
{% block title %}Client Information {% endblock %}
{% block content %}
<h1> Client Form</h1>
<p>Please use the form below to add a new client to the database:</p>
<form method="post" enctype="multipart/form-data">
{{ client_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Save changes"></p>
</form>
{% endblock %}
Everything seems to be working fine, I can submit data in the website and I get a message stating that the the submission when fine, however, when I check the admin website and inspect the database, I can't see the new data added, essentially the form is not submitting data and I don't get an error
[10/Jul/2021 18:36:24] "GET /account/add_client/ HTTP/1.1" 200 12385
[10/Jul/2021 18:36:36] "POST /account/add_client/ HTTP/1.1" 200 12616
Does anyone knows what am I doing wrong?
I notice my mistake is in the form, I should have not use the request.user in the instance, the #login_required is enough informtion.
Please see amended code:
#login_required
def add_client(request):
if request.method == "POST":
client_form = ClientForm(request.POST)
if client_form.is_valid():
client_form.save()
messages.success(request, 'You have successfully added a client')
return HttpResponseRedirect(reverse('add_client'))
else:
messages.error(request, "Error Updating your form")
else:
client_form = ClientForm()
return render(request,
"account/add_client.html",
{'client_form':client_form})
I am trying to update a userprofile model that i used to save additional information over the inbuilt User model, now when i am trying to update it , the image does not gets saved. I need help to resolve this issue
# In views.py
#login_required(login_url=LOGIN_REDIRECT_URL)
def update_user_profile(request):
userobj = get_object_or_404(UserProfile, user=request.user)
form = UserProfileForm(data = request.POST or None,files= request.FILES or None, instance=userobj)
if request.method=='POST':
print(form.is_valid())
if form.is_valid():
profile = form.save(commit=False)
profile.picture = form.cleaned_data['picture']
profile.about = form.cleaned_data['about']
profile.save()
else:
print("NO picure")
return HttpResponseRedirect("/blog/profile/")
return render(request, "blog/post_update.html", {'form':form})
#models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
about = models.CharField(max_length=200, null=True, blank=True)
picture = models.ImageField(upload_to="profile_images/", blank=True)
def __str__(self):
return str(self.user)
#In forms.py
class UserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
self.fields['about'].widget.attrs.update({'class': 'form-control '})
self.fields['picture'].widget.attrs.update({'class': 'form-control-file'})
class Meta:
model = UserProfile
fields = ('about', 'picture')
# userprofileform.html
{% extends 'base.html' %}
{% block content %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary" value="Create Profile">
</form>
{% endblock %}
please take a look at the code and help. while registering if the image was uploaded it get's saved , but when i try to update the userprofile directly in profile section image does not get changed and shows the same as one saved while user registration else it shows None.
I did some changes on templates in settings.py and got my project runnning. Issue was that i was not mentioning the Templates directory properly
i can get data from backend from User e.g user.id but when i want to get data from OneToOneField e.g user.checkAdmin.isAdmin its not displaying any data in html page
views.py
def registerView(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
isAdminForm = checkAdminForm(request.POST) #
if form.is_valid() and isAdminForm.is_valid():
user = form.save()
isAdminFormObject = isAdminForm.save(commit=False)
isAdminFormObject.user = user
isAdminFormObject.save()
return redirect('login_url')
else:
form = UserCreationForm()
isAdminForm = checkAdminForm()
return render(request, 'registration/register.html',{'form':form,'isAdminForm':isAdminForm})
Forms.py
from django import forms
from .models import checkAdmin
class checkAdminForm(forms.ModelForm):
class Meta:
model = checkAdmin
fields = ['isAdmin']
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class checkAdmin(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
isAdmin = models.BooleanField(default=False)
def __str__(self):
return self.user.username
dashboard.html
{% extends 'index.html' %}
{% block content %}
<h1>Welcome, {{ user.id }}</h1>
<h1>check?,{{ user.checkAdmin.isAdmin }}</h1>
<button>Mark Attendance</button> <button>Mark Leave</button> <button>View Attance</button>
Logout
{% endblock %}
use checkadmin instead of checkAdmin
{% extends 'base.html' %}
{% block content %}
<h1>Welcome, {{ user.id }}</h1>
<h1>check?,{{ user.checkadmin.isAdmin }}</h1>
<button>Mark Attendance</button> <button>Mark Leave</button> <button>View Attance</button>
Logout
{% endblock %}
List item
Hello I am django beginner having tough time could someone please help me I don't know what am I doing wrong ?
I am trying to create a form and saving some data through it by using form.save(). And I am new to here also so don't mind any mistakes.
Here is my model:
from django.db import models
from stores.models import Store
class Category(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Product(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
price = models.DecimalField(max_digits=5, decimal_places=5)
image = models.ImageField(upload_to='upload_to/')
category = models.ForeignKey(Category, default='Default', on_delete=models.CASCADE, blank=False, null=False)
store = models.ForeignKey(Store, on_delete=models.CASCADE, blank=False, null=False)
Here is my view:
from django.shortcuts import render, redirect
from .forms import NewPro
def pro(request):
if request.method == 'POST':
form = NewPro(request.POST)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
def product_list(request):
return render(request, 'default/product_list.html')
Here is my form:
from django import forms
from .models import Product
class NewPro(forms.ModelForm):
class Meta:
model = Product
fields = ('name', 'price', 'image','category', 'store',)
default/add_product.html :
{% extends 'default/base.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
<h1>Add Product details</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add Product</button>
</form>{% endblock %}
</html>
Settings.py settings
MEDIA_ROOT = '/home/saifi/Saif_project/final_project/MEDIA_ROOT/upload_to'
I can see some indentation issues in the view - but I'll guess that's just formatting when copying into Stackoverflow.
the form.is_valid() check will validate all your form fields and will only write to the database if all the input fields are valid. If it's not saving, the first place I'd check would be for form errors.
In your template you can render the errors with {{form.errors}} and it will list each field and error.
You forgot request.FILES in your pro view function, you have an image file after all.
def pro(request):
if request.method == 'POST':
form = NewPro(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
Try using the form this way:
<form action="YOUR_URL_HERE" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add Product</button>
</form>
I hope this will help. Welcome aboard ;)
Your indentation is wrong, the else should be for first 'if'
def pro(request):
form = NewPro()
if request.method == 'POST':
form = NewPro(request.POST)
if form.is_valid():
form.save()
return redirect('stores_list')
else:
form = NewPro()
return render(request, "default/add_product.html", {'form': form})
I've seen similar types of problems on here but I still haven't been able to work out my problem. When I save PhotographerProfileForm in my view, the form is rendered correctly but after clicking update/submit nothing is actually saved.
No errors are shown either.
What I have now are the fields are prepopulated and I would like the ability to save over these in the database, but nothing happens and at the moment you can only update it from the admin panel.
models.py
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class PhotographerProfile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=200)
bio = models.TextField(max_length=500)
def __str__(self):
return self.user.username
User.profile = property(lambda u: PhotographerProfile.objects.get_or_create(user=u)[0])
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def create_profile(sender,instance,created,**kwargs):
if created:
profile, new = PhotographerProfile.objects.get_or_create(user=instance)
urls.py
urlpatterns = [
url(r'^profile/$', 'photoprofile.views.photographer_profile', name = 'photographer_profile'),
url(r'^profile/portfolio/$', 'photoprofile.views.photographer_portfolio', name='photographer_portfolio'),
]
views.py
#login_required
def photographer_profile(request):
photographerProfile = PhotographerProfile.objects.get(user=request.user)
form = PhotographerProfileForm(initial={'bio':photographerProfile.bio, 'location':photographerProfile.location})#This means you can prepoulate it
return render_to_response('photographerprofile.html',{'form':form}, RequestContext(request))
if request.method == 'POST':
form = PhotographerProfileForm(request.POST, instance = request.user.profile,)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/profile')
else:
user = request.user
profile = user.profile
form = PhotographerProfileForm()
return render(request, 'photographerprofile.html', {'form':form})
def photographer_portfolio(request):
photographerProfile = PhotographerProfile.objects.get(user=request.user)
return render_to_response('photographerportfolio.html', {'photographerProfile':photographerProfile}, RequestContext(request))
forms.py
class PhotographerProfileForm(forms.ModelForm):
class Meta:
model = PhotographerProfile
exclude = ('user',)
photographerprofile.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h2> Profile</h2>
{% for field in form %}
{{ field.error}}
{% endfor %}
<form action='/accounts/profile/' method='post'>
{% csrf_token %}
{{form|crispy}}
<input type='submit' value='Update'/>
<p>Click <a href='/accounts/profile/portfolio/'>here</a> to view portfolio. </p>
</form>
{% endblock %}
You return in the third line of your view, before the form has been processed. Remove that line.