0
votes

I have been learning the Django tutorial for a few weeks using YT, StackOverflow, Django documentation, and other sources. So, maybe my question goes out of the sense. I hope you will understand my question. If anything is a mistake on my code or you want to give me some suggestions, then reply to me.

I make the site locally on my computer. First of all, I have created a signup page and login page using Django Model.

After User login the site, In profile settings, I have created form field like first_name, last_name, email, mobile_number, date_of_birth, zip_code, address, website, bio, etc.

I have models.py for Account setting

from django.db import models
from django.contrib.auth.models import User

# Create your models here.

class Account(models.Model):
    user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    profile_photo = models.ImageField(upload_to='profile', null=True)
    mobile_number = models.PositiveBigIntegerField(null=True)
    date_of_birth = models.DateField(auto_now_add=False, auto_now=False, null= True)
    zip_code = models.IntegerField(null=True)
    address = models.CharField(max_length=225, null=True)
    website = models.URLField(max_length=100, null=True)
    bio = models.CharField(max_length=225, null=True)

In forms.py

from django import forms
from .models import Account

class AccountForm(forms.ModelForm):
    class Meta:
        model = Account
        fields = '__all__'

In templates

<form class="form mx-auto my-5" method="POST" action="" enctype="multipart/form-data">
    <input name="user" type="hidden" value="{{request.user.id}}" required>
    <div class="form-row">
      <div class="col form-group">
        <label for="first_name" class="font-weight-bold">First name (required):</label>
        <input name="first_name" type="text" id="first_name" class="form-control" placeholder="First name" value="{% if request.user.first_name %}{{request.user.first_name}}{% endif %}" required>
      </div>
      <!-- <div class="col form-group">
        <label for="middle_name">Middle name (optional):</label>
        <input name="middle_name" type="text" id="middle_name" class="form-control" placeholder="Middle name">
      </div> -->
      <div class="col form-group">
        <label for="last_name">Last name (optional):</label>
        <input name="last_name" type="text" id="last_name" class="form-control" placeholder="Last name" value="{% if request.user.last_name %}{{request.user.last_name}}{% endif %}">
      </div>
    </div>
    <div class="form-group">
      <label for="email" class="font-weight-bold">Email address:</label>
      <input name="email" type="email" id="email" class="form-control" value="{{request.user.email}}" placeholder="Your email" required>
    </div>
    <div class="form-row">
      <div class="col form-group">
        <label for="mobile_number" class="font-weight-bold">Mobile number:</label>
        <input name="mobile_number" type="tel" id="mobile_number" class="form-control" placeholder="98********" required>
      </div>
      <div class="col form-group">
        <label for="date_of_birth" class="font-weight-bold">Date of birth:</label>
        <input name="date_of_birth" type="date" id="date_of_birth" class="form-control" required>
      </div>
      <div class="col form-group">
        <label for="zip_code" class="font-weight-bold">Zip code:</label>
        <input class="form-control" id="zip_code" name="zip_code" type="number" min="00000" max="99999" placeholder="55455">
      </div>
    </div>
    <div class="form-row">
      <div class="col form-group">
        <label for="address">Address:</label>
        <input name="address" type="text" id="address" class="form-control" placeholder="Bharatpur-07, Chitwan, Nepal">
      </div>
    </div>
    <div class="form-row">
      <div class="col form-group">
        <label for="website">Website:</label>
        <input name="website" type="url" id="website" class="form-control" placeholder="https://example.com/">
      </div>
    </div>
    <div class="form-row">
      <div class="col form-group">
        <label for="bio">Bio:</label>
        <textarea name="bio" class="form-control" id="bio" rows="5"></textarea>   
      </div>
      <div class="col form-group">
        <br><br>
        <span>Write something about your</span>
      </div>
    </div>
  <button class="btn btn-primary btn-md px-3 my-0 mr-0 float-right" type="submit">Submit</button
</form>

I tried in views.py, it worked.

from django.shortcuts import render, redirect
from .forms import AccountForm
from django.contrib import messages
from django.contrib.auth.models import User

# Create your views here.
def profileSettingsPage(request, pid):
    form = AccountForm()
    if request.method == 'POST':
        form = AccountForm(request.POST, request.FILES)
        if int(request.POST.get('user')) == request.user.id:
            if form.is_valid():
                user = User.objects.get(pk=pid)
                 user.first_name = request.POST.get('first_name')
                 user.last_name = request.POST.get('last_name')
                 user.email = request.POST.get('email')
                 user.save()

                 form.save()

                 messages.success(request, 'Profile saved.')
                 return redirect('profile-settings', pid)
        else:
            messages.warning(request, 'Sorry! You enter other username.')
            return redirect('profile-settings', pid)
    context = {'form':form}
    return render(request, 'profile-settings.html', context) 

But, I want to validate for first_name, last_name, email field before saving. I was expecting some is_valid() to save.

Also, I tried something new

Now, In views.py I added

from pages.forms import CreateUserForm

which was created for signup page

Then, views.py looks like this:

from django.shortcuts import render, redirect
from .forms import AccountForm

from pages.forms import CreateUserForm

from django.contrib import messages
from django.contrib.auth.models import User

# Create your views here.
def profileSettingsPage(request, pid):
    form1 = AccountForm()
    form2 = CreateUserForm()
    if request.method == 'POST':
        form1 = AccountForm(request.POST, request.FILES)
        form2 = CreateUserForm(request.POST)
        if int(request.POST.get('user')) == request.user.id:
            if form1.is_valid() and form2.is_valid():
                form2.save()
                form1.save()

                messages.success(request, 'Profile saved.')
                return redirect('profile-settings', pid)
            else:
                messages.warning(request, 'Faile to saved profile')
                return redirect('profile-settings', pid)
        else:
            messages.warning(request, 'Sorry! You enter other username.')
            return redirect('profile-settings', pid)
    context = {'form1':form1, 'form2':form2}
    return render(request, 'profile-settings.html', context)

But, This is not worked for me. form1.is_valid() and form2.is_valid() can not pass True value and give me message "Failed to saved profile."

My question is, I want to update the first_name, last_name, email field of the Django model User, and other fields are separately updated to the next model.

Another question

In the above models.py, I have use ForeignKey() to get the User(username or id).

In templates, I have used {{ request.user.id }} to get user.

Is it possible to get User (id or username) without touching views.py, forms.py and templates?

Edit: I got an answer on this link: I am unable to update two models at the same time in Django Views.py

2
Did you check if your `{{ request.user.if }} is returning any ID or not? Because you haven't passed in the request variable in the context for the template.BATMAN
Also, if you just want to update the model, you can pass in the instance of user to your user_form while creating its object. That way you won't even need to pass in the id of the user to the template.BATMAN
Yes, {{request.user.id}} give me id. But in views.py, I checked request.POST.get('user') == request.user.id and it return False although value is same.Then, i found somewhere, convert id to int. Then I checked int(request.POST.get('user')) == request.user.id. Finally it worked. But my question is like in models.py is there any possible like user = request.user.id instead of ForeignKeyJS TECH
For the update model, @BATMAN can you give a sample code of passing instance. Because it tried a lot or I mistake somewhere, it only updated AccountForm only not django UserJS TECH
Did you fix your problem for update and the id you were looking for?BATMAN

2 Answers

0
votes

You can simply pass the user_id in the context to the template and then use it.

0
votes
class Account(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.SET_NULL)
    profile_photo = models.ImageField(upload_to='profile', null=True)
    mobile_number = models.PositiveBigIntegerField(null=True)
    date_of_birth = models.DateField(auto_now_add=False, auto_now=False, null= 
    True)
    zip_code = models.IntegerField(null=True)
    address = models.CharField(max_length=225, null=True)
    website = models.URLField(max_length=100, null=True)
    bio = models.CharField(max_length=225, null=True)

def profileSettingsPage(request):
    form1 = AccountForm()
    form2 = CreateUserForm()
    if request.method == 'POST':
        instance_user = User.objects.get(pk=request.user.id)
        instance_account = Account.objects.get(user=instance_user)
        form1 = AccountForm(request.POST, request.FILES,instance=instance_account)
        form2 = CreateUserForm(request.POST,instance=instance_user)

        if form1.is_valid() and form2.is_valid():
            form2.save()
            form1.save()
            messages.success(request, 'Profile saved.')
            return redirect('profile-settings')
        else:
            print(form1.errors)
            print(form2.errors)
            messages.warning(request, 'Faile to saved profile')
            return redirect('profile-settings')
    context = {'form1':form1, 'form2':form2}
    return render(request, 'profile-settings.html', context)