Как обновить профиль другого пользователя, если вы вошли в систему как владелец?
В настоящее время я вошел в систему как владелец и хочу обновить поля клиентов в базе данных. Но форма не обновляется или показывает данные в виде заполнителя, потому что модель пользователя расширила модель клиента и, следовательно, модель клиента не имеет собственных полей. Как мне получить экземпляр User модели Customer в UpdateView?/Как мне обновить клиента?
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',
)
Итак, на данный момент я должен предположить несколько вещей... Допустим, у вас есть ListView
для вывода списка клиентов.
views.py
файл:
class CustomerListView(OwnerAndLoginRequiredMixin, generic.ListView):
template_name = "customer_update.html"
queryset = Customer.objects.all()
context_object_name = 'customers'
urls.py
файл:
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
файл:
{% 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 %}
Возврат к файлу views.py
:
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"
Теперь в пределах customer_update.html
:
<form method="POST">
<div>
{{ form.username }}
{{ form.email }}
{{ form.first_name }}
{{ form.last_name }}
</div>
<input type="submit" value="Update"/>
</form>
Идеально, это должно отображать информацию о клиенте в форме.
UPDATES
Для обработки и сохранения отправки формы можно использовать post()
на update-view
. Вы можете добавить к 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})