Home > Back-end >  How to update the user profile of a different user if you are logged in as the owner?
How to update the user profile of a different user if you are logged in as the owner?

Time:06-19

Currently, I am logged in as an owner and I want to update the fields of customers in the database. But the form does not update or show the details as a placeholder because the user model has extended the customer model and hence, the customer model does not have its own fields. How do I get the instance of the User of the Customer in the UpdateView?/How do I update the customer?

urls.py

urlpatterns = [
path('<int:pk>/update/',CustomerUpdateView.as_view()),
]

views.py

class CustomerUpdateView(OwnerAndLoginRequiredMixin, generic.UpdateView):
    template_name = "customer_update.html"
    form_class = CustomerModelForm
    queryset = Customer.objects.all()

    def get_success_url(self):
        return "/customers"

models.py

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

class User(AbstractUser):
    is_owner = models.BooleanField(default=True)
    is_agent = models.BooleanField(default=False)
    is_customer = models.BooleanField(default=False)

forms.py

class CustomerModelForm(forms.ModelForm):
class Meta:
    model = User
    fields = (
        'email',
        'username',
        'first_name',
        'last_name',
    )

CodePudding user response:

So at this point, I'd have to assume a few things here... Let's say you have a ListView to render a list of customers.

views.py file:

class CustomerListView(OwnerAndLoginRequiredMixin, generic.ListView):
     template_name = "customer_update.html"
     queryset = Customer.objects.all()
     context_object_name = 'customers'

urls.py file:

urlpatterns = [
     ...
     path('customers/', CustomerListView.as_view(), name='customers'),
     path('update-customer/<int:pk>/', CustomerUpdateView.as_view(), name='update-customer'),
     # You can pass whatever customer related info you wish via url, I'm just using id as a simply demo.
     ...
]

html file:

{% for customer in customers %}
     # Displaying other related info per customer

     # Link to click to update a particular customer profile: passing the customer pk via url
     <a href="{% url 'update-customer' customer.pk %}"> Update {{ customer.user.username|title }} Profile </a>
{% endfor %}

Back to the views.py file:

class CustomerUpdateView(OwnerAndLoginRequiredMixin, generic.UpdateView):
     template_name = "customer_update.html"
     form_class = CustomerModelForm
     # context_object_name = 'customer'
     # queryset = Customer.objects.all() # not needed here

     # You can use the get_object() on the class to grab the customer object by the pk passed via url
     def get_object(self, queryset=None):
          customer_pk = self.kwargs.get('pk', None)

          return get_object_or_404(Customer, pk=customer_pk)

     # Also, you could use the get_context_data() to set the form values before rendering on the page
     def get_context_data(self, **kwargs):
          context = super().get_context_data(**kwargs)
          
          customer = self.get_object()  # -> returns a customer object

          # creating a dictionary to use to initialize the form: accessing the user information on the customer
          data = {
               'username': customer.user.username,
               'first_name': customer.user.first_name,
               'last_name': customer.user.last_name,
               'email': customer.user.email,
          }

          form = self.form_class(initial=data, instance=customer.user) # updated here too

          context['form'] = form  # -> updating the class view context dictionary
          return context

     def get_success_url(self):
          return "/customers"

Now within the customer_update.html:

<form method="POST">
     <div>
          {{ form.username }}

          {{ form.email }}

          {{ form.first_name }}

          {{ form.last_name }}
     </div>
     
     <input type="submit" value="Update"/>
</form>

Ideally, that should display the customer's information in the form.

UPDATES

To handle and save the form submission, you can use the post() on the update-view. You can add to the CustomerUpdateView:

# Use the post method to handle the form submission
def post(self, request, *arg, **kwargs):

     # Should set the user instance on the form
     customer = self.get_object()
     form = self.form_class(request.POST, instance=customer.user)  # updated here too
     
     if form.is_valid():
          form.save()

          return redirect('to any path of your choice') # Redirect upon submission if necessary
     else:
          print(form.errors)  # To see the field(s) preventing the form from being submitted

     # Passing back the form to the template
     return render(request, self.template_name, {'form': form})
  • Related