[PYTHON] Django: User Agent aufzeichnen und mit Admin verwalten

Projekterstellung

startproject

(v17)hdknr@wzy:~/ve/v17/src$ mkdir -p ua/web
(v17)hdknr@wzy:~/ve/v17/src$ django-admin startproject app ua/web
(v17)hdknr@wzy:~/ve/v17/src$ cd ua/web
(v17)hdknr@wzy:~/ve/v17/src/ua/web$ python manage.py migrate
(v17)hdknr@wzy:~/ve/v17/src/ua/web$ python manage.py createsuperuser

Konten hinzufügen

(v17)hdknr@wzy:~/ve/v17/src/ua/web$ python manage.py startapp accounts

app/settings.py

INSTALLED_APPS += (
    'accounts',
)

app/urls.py

    url(r'^accounts/', include('accounts.urls')),

accounts/urls.py

from django.conf.urls import patterns, url
import views

urlpatterns = patterns(
    '',
    url(r'login/$', 'django.contrib.auth.views.login'),
    url(r'profile/$', views.profile),
)

accounts/views.py

from django.contrib.auth.decorators import login_required
from django.template.response import TemplateResponse

import models


@login_required
def profile(request):
    ua = None
    return TemplateResponse(
        request,
        'registration/profile.html',
        dict(request=request, ua=ua, ))

accounts/templates/registration

(v17)hdknr@wzy:~/ve/v17/src/ua/web$ mkdir -p accounts/templates/registration
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
{{ request.user }}
{{ ua }}

UserAgent-Modell

UA-Urteil (account / ua.py)

--agent_type (): Sucht einen passenden Agenten mit einem kanonischen Ausdruck

import re


DETECTOR = [
    # Featured Phone
    r'(?P<agent>DoCoMo)',
    r'(?P<agent>SoftBank)',
    r'^(?P<agent>KDDI)',     # if no KDDI, HDML browser.
    r'(?P<agent>Vodafone)',

    ....
]


def agent_type(agent_string):
    for d in DETECTOR:
        m = re.search(d, agent_string, flags=re.IGNORECASE)
        m = m and m.groupdict() or {}
        if m:
            return m['agent'].lower().replace('-', '').replace(' ', '')
    return "generic"

Modelle (accounts / models.py)

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

from ua import agent_type
import hashlib

class UserAgent(models.Model):
    agent = models.CharField(
        _(u'User Agent'),
        max_length=30, default="PC")
    key = models.CharField(
        _(u'User Agent Header MD5 Hash'),
        max_length=40, unique=True, db_index=True,)
    header = models.CharField(
        _(u'User Agent Header'),  max_length=512, )
    users = models.ManyToManyField(
        User, default=None, null=True, blank=True)


    @classmethod
    def get_ua(cls, ua_header, user=None):
        ua, created = cls.objects.get_or_create(
            key=hashlib.md5(ua_header).hexdigest())

        if created:
            ua.agent = agent_type(ua_header)
            ua.header = ua_header
            ua.save()

        if user:
            ua.users.add(user)

        return ua

    def __unicode__(self):
        return "%s(%s)" % (self.agent, getattr(self, 'id', ''))

Datensatz in / accounts / profile (accounts / views.py)

--Fixiertes Profil ()

@login_required
def profile(request):
    ua = models.UserAgent.get_ua(
        request.META.get('HTTP_USER_AGENT', 'N/A'),
        request.user)

    return TemplateResponse(
        request,
        'registration/profile.html',
        dict(request=request, ua=ua, ))

Meine große

(v17)hdknr@wzy:~/ve/v17/src/ua/web$ python manage.py makemigrations accounts
Migrations for 'accounts':
  0001_initial.py:
    - Create model UserAgent
(v17)hdknr@wzy:~/ve/v17/src/ua/web$ python manage.py migrate  accounts
Operations to perform:
  Apply all migrations: accounts
Running migrations:
  Applying accounts.0001_initial... OK

accounts/admin.py

from django.contrib import admin
import models


class UserAgentAdmin(admin.ModelAdmin):
    list_display = tuple(
        [f.name for f in models.UserAgent._meta.fields
         if f.name not in ['key']]
    )

admin.site.register(UserAgent, UserAgentAdmin)

Admin-Anpassung

UserAgentAdmin(accounts/admin.py)

1. Filtern nach Agentenfeld

    list_filter = ('agent', )    

2. Machen Sie das Benutzerfeld unbearbeitbar

    add_exclude = ('users',)
    edit_exclude = ('users',)

    def add_view(self, *args, **kwargs):
        self.exclude = getattr(self, 'add_exclude', ())
        return super(UserAgentAdmin, self).add_view(*args, **kwargs)

    def change_view(self, *args, **kwargs):
        self.exclude = getattr(self, 'edit_exclude', ())
        return super(UserAgentAdmin, self).change_view(*args, **kwargs)

3. Zeigen Sie die Anzahl der mit UserAgent angemeldeten Benutzer an und verknüpfen Sie sie mit der Liste

from django.core.urlresolvers import reverse
    list_display = tuple(
        [f.name for f in models.UserAgent._meta.fields
         if f.name not in ['key']]
    ) + ('users_count',)

    def users_count(self, obj):
        if not obj.users.exists():
            return '0'

        uri = reverse("admin:%s_changelist" % obj.users.model._meta.db_table)
        query = "?useragent__id__exact=%d" % (obj.id)
        return mark_safe(
            u"<a href='%s'>%d Users</a>" % (uri + query, obj.users.count()))

    users_count.allow_tags = True

image

4. Anstatt das Benutzerfeld nicht zu bearbeiten, zeigen Sie einen Link zum angemeldeten Benutzer an

    readonly_fields = ('ua_users', )

    def ua_users(self, instance):
        try:
            return ",".join([
                mark_safe('<a href="%s">%s</a>   ' % (
                    reverse("admin:%s_change" % u._meta.db_table, args=[u.id]),
                    u.__unicode__()))
                for u in instance.users.all()])
        except:
            return "errors"

    ua_users.short_description = "UserAgent Users"
    ua_users.allow_tags = True

image

UserAdmin(accounts/admin.py)

from django.db.models.manager import Manager
from django.utils.safestring import mark_safe
from django.contrib.auth.admin import UserAdmin
def link_to_relation(self, obj, field=""):
    fobj = obj and getattr(obj, field, None)

    if fobj is None:
        return "No Link"

    if issubclass(fobj.__class__, Manager):
        fobj = fobj.all()
    else:
        fobj = [fobj, ]

    return mark_safe("<br/>".join([
        '<a href="%s">%s</a>' % (
            reverse("admin:%s_change" % ln._meta.db_table, args=[ln.id]),
            ln.__unicode__()
        ) for ln in fobj]))

--Erstellen Sie einen Backlink mit dem Benutzerobjekt und useragent_set

useragent_link = lambda self, obj: link_to_relation(self, obj, "useragent_set")
useragent_link.short_description = u"User Agent"
useragent_link.allow_tags = True
UserAdmin.list_display = tuple(
    set(UserAdmin.list_display + ('useragent_link', )))
UserAdmin.useragent_link = useragent_link
UserAdmin.list_filter = UserAdmin.list_filter + ('useragent__agent',)

――Du kannst damit zurückgehen

image

Recommended Posts

Django: User Agent aufzeichnen und mit Admin verwalten
HTTPS mit Django und Let's Encrypt
Verwalten Sie Django-Konfigurationsdateien mit Python-Decouple
CentOS 6.4, Python 2.7.3, Apache, mod_wsgi, Django
Ramen-Kartenerstellung mit Scrapy und Django
Zeichnen Sie die letzte Zugriffszeit des Benutzers mit Redis auf
Verwalten Sie Django-Bilder und statische Assets unter Ubuntu
Generieren und veröffentlichen Sie Dummy-Bilddaten mit Django
Verwalten Sie die Umgebung deklarativ mit Nix und Home-Manager
Verwalten Sie Statusübergänge und kommunizieren Sie mit intelligenten Zählern
Internationalisierung mit Django
CRUD mit Django
Notieren Sie Temperatur und Luftfeuchtigkeit mit systemd auf Raspberry Pi
Weitere neue Benutzerauthentifizierungsmethoden mit Django REST Framework
Erstellen Sie eine API für die Benutzerauthentifizierung mit Django REST Framework
Implementieren Sie die Django-Benutzererweiterung und registrieren Sie die angehängten Informationen
Rufen Sie die aktuellen Standortinformationen und den Benutzeragenten in Python ab
Verwalten Sie Python-Laufzeitpakete und Entwicklungsumgebungspakete mit Poetry
[Python] Mit der API von Qiita erhalten Sie Benutzer- und Artikelinformationen