Updating a profile image in django - django-models

so I have this issue when trying to update a profile photo in django.
The Profile photo actually updates if I upload an image. But there are cases where a user may want to update other details on the profile update page without having to update the profile photo.
Trying to implement that gave me a multivalue error.
I've been on it for some time now, Please, who knows how I can handle that.
Here's my code on views.py file
def profile_update(request, user_id):
if request.method == 'POST':
user_obj = User.objects.get(id=user_id)
user_profile_obj = UserProfile.objects.get(user=user_id)
user_img = request.FILES['user_img']
username = request.POST["username"]
email = request.POST["email"]
phone = request.POST["phone"]
address = request.POST["address"]
fs_handle = FileSystemStorage()
img_name = 'uploads/profile_pictures/user_{0}'.format(user_id)
if fs_handle.exists(img_name):
fs_handle.delete(img_name)
fs_handle.save(img_name, user_img)
user_profile_obj.profile_pic = img_name
user_profile_obj.phone = phone
user_profile_obj.address = address
user_profile_obj.save()
user_obj.username = username
user_obj.email = email
user_obj.save()
user_obj.refresh_from_db()
Here's my models.py file
`
class UserProfile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
address = models.CharField(max_length=65, null=True, blank=True)
phone = models.CharField(max_length=65, null=True, blank=True)
profile_pic = models.FileField(null=True, blank=True, upload_to="uploads/profile_pictures", validators = [FileExtensionValidator(allowed_extensions=['jpg','jpeg','png'])])
def __str__(self):
return str(self.user)
`

Related

Creating a simple messaging function (NOT REAL TIME) using Django

Please I'm trying to implement a SIMPLE messaging function (NOT A REAL TIME CHAT)
But I keep getting this error message I understand what it says or mean but I'm not sure why I am unable to establish this relationship
Please I need help to alternative if I can't do things this way
This is my profile(Engineer) models
class Engineer(AbstractUser):
username = models.CharField(max_length=200, null=True)
email = models.EmailField(unique=True, null=True)
bio = models.TextField()
avatar = models.ImageField(default="profile.png")
country = models.CharField(max_length=200)
years_of_experience = models.PositiveIntegerField(null=True, blank=True)
tech_stack = models.CharField(null=True, blank=True, max_length=300)
inbox = models.ForeignKey(Inbox, null=True, on_delete=models.CASCADE)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
def __str__(self):
return self.username
and this is my Inbox models
class Inbox(models.Model):
sender = models.ForeignKey(Engineer, null=True, on_delete=models.CASCADE, related_name='mail_sender')
receiver = models.ForeignKey(Engineer, null=True, on_delete=models.CASCADE, related_name="mail_receiver")
message = models.CharField(max_length=500)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return self.sender.username
Just make the Engineer import as follows
sender = models.ForeignKey('Engineer', null=True, on_delete=models.CASCADE, related_name='mail_sender')
receiver = models.ForeignKey('Engineer', null=True, on_delete=models.CASCADE, related_name="mail_receiver")

Please explain the _set.all() method in django>

I have this models and the view for user profile.
class Room(models.Model):
admin = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
group_photo = models.ImageField(null=True, upload_to = 'images/', default='avatar.svg')
name = models.CharField(unique=True, max_length=100)
description = models.TextField(null=True, blank=True)
members = models.ManyToManyField(User, related_name='members', blank=True)
created = models.DateTimeField(auto_now_add=True)
views.py
#login_required(login_url= 'login')
def userprofile(request, pk):
user = User.objects.get(username=pk)
#groups = user.room_set.all()
groups = Room.objects.filter(admin=user)
all_groups = Room.objects.filter(members=user)
return render(request, 'base/profile.html', {'user':user, 'groups':groups, 'all_groups':all_groups})
Please explain how _set.all method filter method are doing the same job.
I don't understand where the room is coming from (there is only (Room) model.
explain the mechanism of user.room_set.all line respect to filter;

Authentication failure: Login page returns DoesNotEXist for users already in the database

I am trying to grasp Python Django. I'm trying to make a bank system web application. I can register users. These users then are automatically logged in. However, after logout I cannot login the same user again. The page tells me the user does not exist
I have tried to play around with my backends.py in the terminal. when i run
$ user=User.objects.get(pk=1)
$ user
it returns the user with the id in the database. However it doesnt work with the login page. Kindly help, I have been stuck for a week.
models.py:
class UserManager(BaseUserManager):
def create_user(self, account_no, password=None, **extra_fields):
"""
Create and save a user with the given account_no and password.
"""
user = self.model(account_no=account_no, **extra_fields)
user.set_password(password)
user.save(using=self._db)
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return user
def create_superuser(self, email, password, **extra_fields):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(email, password=password, **extra_fields)
user.is_admin = True
user.save(using=self._db)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('account_no', False)
extra_fields.setdefault('is_superuser', True)
return user
class User(AbstractUser):
username = models.CharField(
('username'), max_length=30, unique=True, null=True, blank=True)
email = models.EmailField(unique=True, blank=True, null=True)
contact_no = models.IntegerField(unique=False, null=True,blank=True)
account_no = models.PositiveIntegerField(
unique=True,
validators=[
MinValueValidator(1000000000),
MaxValueValidator(9999999999)
])
balance = models.DecimalField(
default=0,
max_digits=12,
decimal_places=2
)
GENDER_CHOICE = (
("M", "Male"),
("F", "Female"),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICE)
birth_date = models.DateField(null=True, blank=True)
city = models.CharField(max_length=256, blank=True, null=True)
postal_code = models.PositiveSmallIntegerField(blank=True, null=True)
country = models.CharField(max_length=256, blank=True, null=True)
picture = models.ImageField(
null=True,
blank=True,
upload_to='account_pictures/',
)
objects = UserManager()
USERNAME_FIELD = 'account_no'
REQUIRED_FIELDS = ['first_name', 'last_name', ]
def __str__(self):
return str(self.full_name)
views.py:
def login_view(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = UserLoginForm(request.POST)
if form.is_valid():
account_no = form.cleaned_data.get('account_no')
password = form.cleaned_data.get('password')
user = authenticate(account_no=account_no, password=password)
login(request, user, backend='accounts.backends.ModelBackend')
messages.success(request, 'Welcome, {}!'.format(user.full_name))
return redirect("home")
context = {"form": form,
"title": "Load Account Details",
}
return render(request, "accounts/login.html", context)
backends.py:
from django.contrib.auth import get_user_model
User = get_user_model()
class ModelBackend(object):
def authenticate(self, request, account_no=None, password=None):
try:
user = User.objects.get(account_no=account_no)
if user and user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
forms.py:
class UserLoginForm(forms.Form):
account_no = forms.IntegerField(label="Account Number")
password = forms.CharField(widget=forms.PasswordInput)
def clean(self, *args, **kwargs):
account_no = self.cleaned_data.get("account_no")
password = self.cleaned_data.get("password")
if account_no and password:
user = authenticate(account_no=account_no, password=password)
if not user:
raise forms.ValidationError("Account Does Not Exist.")
if not user.check_password(password):
raise forms.ValidationError("Password Does not Match.")
if not user.is_active:
raise forms.ValidationError("Account is not Active.")
return super(UserLoginForm, self).clean(*args, **kwargs)
The user that has been registered should be able to login. The program keeps denying registered users from logging in.

how to filter foreign key in django form without passing foreign key value?

I have created two models in my django project AddStudent and Fee Entry as shown below.
models.py
class AddStudent(models.Model):
enrollment_no = models.BigIntegerField(primary_key=True)
student_name = models.CharField(max_length=500,null=True)
gender = models.CharField(max_length=1,choices=GENDER_CHOICES)
course = models.ForeignKey(CourseMaster, on_delete=models.DO_NOTHING, null=True)
category= models.ForeignKey(CatMaster, on_delete=models.DO_NOTHING, null=True)
admission_year = models.IntegerField(('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
college = models.ForeignKey(CollegeMaster, on_delete=models.DO_NOTHING, null=True)
branch = models.ForeignKey(BranchMaster,on_delete=models.DO_NOTHING, null=True)
current_semester = models.IntegerField(null=True)
address = models.CharField(max_length=1000,null=True)
city = models.CharField(max_length=100,null=True)
district = models.CharField(max_length=100,null=True)
state = models.CharField(max_length=100,null=True)
student_contact = models.BigIntegerField()
parent_contact = models.BigIntegerField()
def get_absolute_url(self):
return reverse('add_student:index')
def __str__(self):
return str(self.enrollment_no) + ' - ' + self.student_name
class FeeEntry(models.Model):
student = models.ForeignKey(AddStudent,on_delete=models.DO_NOTHING)
fee_detail = models.ForeignKey(FeeMaster,on_delete=models.DO_NOTHING)
fee_sem = models.IntegerField(null=True)
payment_date = models.DateField(("Date"), default=datetime.date.today)
pay_method = models.BooleanField(choices=BOOL_CHOICES)
cheque_no = models.CharField(max_length = 100, null=True, blank=True)
bank_name = models.CharField(max_length = 200, null=True, blank=True)
def __str__(self):
return str(self.id) + ' - ' + str(self.student) + ' - ' + self.student.student_name
Now when user search particular student for example student id = 1 than student profile page will open and there is another button addfee. My problem is when user click on add fee all 500 student list is appear in dropdown list. i want to create fee for searched student only.
forms.py
from django import forms
from .models import FeeEntry, AddStudent
from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
class FeeForm(PopRequestMixin, CreateUpdateAjaxMixin, forms.ModelForm):
class Meta:
model = FeeEntry
fields = ['student', 'fee_detail', 'fee_sem', 'payment_date', 'pay_method','cheque_no','bank_name']
above is my forms.py file where field 'student' will generate all 500 student list. I want only selected student for example enrollment_no=1 when user is on enrollment_no 1's page.
views.py
class FeeCreateView(PassRequestMixin, SuccessMessageMixin,
generic.CreateView):
template_name = 'add_student/create_fee.html'
form_class = FeeForm
success_message = 'Success: Book was created.'
success_url = reverse_lazy('add_student:detail')
urls.py
path('create/<int:pk>', views.FeeCreateView.as_view(), name='create_fee'),
Can anyone tell me what changes are required in this code? or can you share link of similar example like this?
The FeeForm does not know which student you want to relate it with. Because of that, it is showing you a dropdown asking which student you want to assign to the FeeEntry instance.
Remove 'student' from the form and send the form to the view. when the user submits the form, use the form_valid (form.is_valid if you are using FBV) method to assign the student to the fee_entry instance.
def form_valid(self, form):
fee_entry = form.save(commit=False)
fee_entry.student = AddStudent.objects.get(id=self.kwargs['student_id'])
fee_entry.save()
Also make sure to send the student_id in the url. You can even send it as a POST parameter(check out how to retrieve parameter from a POST request) using a hidden field in the form.

How to build a form for nested models?

I am building an app in Django 1.9 with the models Customers and Addresses:
class Customers(models.Model):
name = models.CharField(db_column='NAME', max_length=400)
email = models.CharField(db_column='EMAIL', max_length=255, unique=True)
phone_number = models.CharField(db_column='PHONE_NUMBER', max_length=200, blank=True, null=True)
address = models.ForeignKey(Addresses, db_column='ADDRESS_ID', related_name='customer_address', null=True)
class Addresses(models.Model):
street = models.TextField(db_column='STREET', max_length=2000)
city = models.CharField(db_column='CITY', max_length=400, blank=True, null=True)
postal_code = models.CharField(db_column='POSTAL_CODE', max_length=200, blank=True, null=True)
country = models.ForeignKey(Country, db_column='COUNTRY_ID', null=True)
I am new in Django, so please forgive me if this has too much mistakes.
I want to create a new Customer using a form:
class CustomersForm(ModelForm):
name = forms.CharField(label=_(u'Name'), widget=TextInput())
email = forms.CharField(label=_(u'Email'), widget=TextInput())
phone_number = forms.IntegerField(label=_(u'Phone Number'), required=False, widget=TextInput(attrs={'style': 'width:80px'}))
But I still want to be able to add the address. I read some stuff about nested forms, but I didn't understand.
Could you, please, help in building a form that creates a Customer with name, email, phone_number and address?
I figured it out! :)
You have to override the save method of the form.
class CustomersForm(ModelForm):
name = forms.CharField(label=_(u'Name'), widget=TextInput())
email = forms.CharField(label=_(u'Email'), widget=TextInput())
a_street = forms.CharField(label=_(u'Street'), widget=TextInput(), required=False)
a_postal_code = forms.CharField(label=_(u'Postal Code'), widget=TextInput(), required=False)
a_city = forms.CharField(label=_(u'City'), widget=TextInput(), required=False)
a_country = forms.CharField(label=_(u'Country'), widget=TextInput(), required=False)
# Override the save method like this
def save(self, commit=True):
c = super(CustomersForm, self).save(commit=False)
# Address
if c.address:
a = c.address
else:
a = Addresses()
a.street = self.cleaned_data.get('a_street')
a.city = self.cleaned_data.get('a_city')
a.postal_code = self.cleaned_data.get('a_postal_code')
a.country = self.cleaned_data.get('a_country')
if commit:
a.save()
c.address = a
c.save()
return c

Resources