#python #django #django-models
#python #django #django-модели
Вопрос:
У меня есть модель (UserProfile), с помощью которой я хочу записывать IP-адрес пользователя при создании новых учетных записей пользователей.
Я начал процесс переопределения метода save () модели Django, но я совершенно не уверен, как правильно получить доступ к атрибутам HttpRequest изнутри модели. Кто-нибудь из вас, ребята, может помочь? Google не смог предоставить конкретный ответ для меня.
Ответ №1:
Вы можете получить доступ к запросу от администратора, но вы не можете сделать это в общем коде. Если вам это нужно, вам придется назначить его вручную в представлении.
Комментарии:
1. Действительно? Нет способа объявить self.ip_address = запрос. META[‘REMOTE_ADDR’] из метода save() модели?
2. Нет способа получить доступ к запросу из любого места, кроме того, куда он явно отправлен.
3. @tommytwoeyes Нет, модели честно независимы даже от самого HTTP, поэтому понятие «запрос» для них ничего не значит. Разделение проблем!
4. Хорошо, это понятно. Однако, если я могу установить атрибут ip_address пользовательского профиля только из представления, не слишком ли тесно это связывает представление и модель? И если мне нужно изменить ip_address пользовательского профиля откуда-то еще, и я повторяю свой код для этого, не является ли это несколько непитоновским? Не пытаюсь казаться аргументированным — я просто действительно новичок в Python и Django и пытаюсь понять наилучший способ добиться этого. Спасибо!
5. Если вы хотите соединить их вместе и нарушить DRY, то это ваша прерогатива. Но не просите Django делать ни то, ни другое.
Ответ №2:
Вам всегда нужно передавать информацию о запросе из представления в ваш метод сохранения. Учтите, что сохранение экземпляра не всегда должно вызываться из http-запроса (для простого примера подумайте о вызове save
в оболочке python).
Если вам нужно получить доступ к request
объекту в admin во время сохранения, вы можете переопределить этот save_model
метод:
def save_model(self, request, obj, form, change):
# do something with obj and request here....
obj.save()
Но в противном случае вам всегда приходится передавать его из представления:
def my_view(request):
obj = MyClass(ip_address = request.META['REMOTE_ADDR'])
Или, чтобы упростить повторное использование, создайте в модели метод, подобный:
def foo(self, request):
self.ip_address = request.META['REMOTE_ADDR']
self..... = request.....
и вызвать его из вашего представления с помощью obj.foo(request)
.
Комментарии:
1. Спасибо. Тогда, я думаю, я помещу это в представление регистрации. Поместить его в метод save_model() администратора не получится, потому что, если бы я записал значение REMOTE_ADDR, когда один из администраторов нашего сайта создавал учетную запись пользователя через администратора, он записал бы ее IP-адрес вместо пользовательского.