Как получить доступ к REMOTE_ADDR в методе save() модели

#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-адрес вместо пользовательского.