django #django-models #django-views #django-forms #django-templates
#django #django-модели #django-views #django-forms #django-шаблоны
Вопрос:
Я хочу изменить первичный ключ, отправляемый в представление обновления из шаблона. Позвольте мне объяснить. Вот мой шаблон:
<a href="{% url 'new_url' model_instance.pk %}">
{{ model_instance.username }}
</a>
Это model_instance
экземпляр в цикле for контекстной переменной model_instances
в представлении списка. Затем этот первичный ключ model_instance будет отправлен в следующее представление:
class UserUpdateView(generic.UpdateView):
template_name = "leads/update.html"
queryset = User.objects.all()
context_object_name = "user"
form_class = UserUpdateForm
def get_success_url(self):
return reverse("some-url")
Однако проблема в том, что первичный ключ, на который я отправляю UserUpdateView
, является первичным ключом для model_instance
модели, а не User
для модели. Более того, между двумя моделями нет связи, подобной взаимно однозначным отношениям. Однако есть сходство. Оба model_instance
и user
каждый имеют username
одинаковое поле.
Другими словами, мне нужно сначала получить model_instance.username
, а затем запросить User
модель, чтобы найти user
экземпляр с тем же username
, который я хочу обновить. На данный момент UserUpdateView
просто получает первичный ключ для a model_instance
в шаблоне, чего я не хочу. Я надеюсь, что вы, ребята, сможете помочь мне с этой проблемой, и, пожалуйста, оставьте любые вопросы, которые у вас есть. Спасибо.
Ответ №1:
Это недостаточно интуитивно понятно, но да, это возможно. Также полезно упомянуть, что вы определяете queryset
атрибут в представлении, если вы хотите обновить только один объект, тогда в этом нет необходимости. Вы можете переопределить get_object
метод для этого :
class UserUpdateView(generic.UpdateView):
template_name = "leads/update.html"
# queryset = User.objects.all()
context_object_name = "user"
form_class = UserUpdateForm
def get_success_url(self):
return reverse("some-url")
def get_object(self):
# Here w'll retrieve the correct object to update
# First we retrieve the username of the model_instance
model_instance = ModelInstance.objects.get(pk=self.kwargs['pk'])
username = model_instance.username # Retrieve the username
# After, retrieve the user with username=model_instance.username
# Normally, the username must be unique per model_instance and per user. If not an error can be trowed.
user = User.objects.get(username=username)
# If username is not unique, try this approach
# user = User.objects.filter(username=username).first()
# Return the user object
return user
Эта ссылка на шаблон :
<a href="{% url 'new_url' model_instance.pk %}">
{{ model_instance.username }}
</a>
теперь будет указывать пользователю на обновление, а не на model_instance.
Подробнее о get_object
Комментарии:
1. Эй, ты вернулся
user
из-заuser = User.objects.get(username=username)
? Если вы определили его какsomethingelse = User.objects.get(username=username)
, тогда я должен вернутьсяsomethignelse
?2. @code builder, да, конечно
Ответ №2:
Поскольку model_instance и user имеют одно и то же имя пользователя, вы можете передать model_instance.username
при генерации URL-адреса и изменить свой UpdateView на specify slug_field = "username"
. Вам также придется изменить свой urlconfig, чтобы использовать «slug» вместо «pk» или add slug_url_kwarg = "pk"
.
<a href="{% url 'new_url' model_instance.username %}">
{{ model_instance.username }}
</a>
class UserUpdateView(generic.UpdateView):
template_name = "leads/update.html"
queryset = User.objects.all()
context_object_name = "user"
form_class = UserUpdateForm
slug_field = "username"
slug_url_kwarg = "pk"
def get_success_url(self):
return reverse("some-url")