4

Djangoプロジェクトがあり、電話で電話をかけるたびにユーザーアカウントが作成されます。その人は、後で、自分のアカウントを使用して当社のWebサイトにログインする場合と使用しない場合があります。

質問:ユーザーが当社のWebサイトにログインしたことがあるかどうかを確認するにはどうすればよいですか?

明確化:この時点から作成された新しいユーザーだけでなく、何百人もの既存のユーザーについて上記の質問に答えたいと思います。

考え1:チェックUser.last_login。残念ながら、Djangoは、ログインしたかどうかに関係なく、ユーザーが作成されたときにlast_login初期化されます。datetime.datetime.now()

考え2:User.last_login一致するかどうかを確認しUser.date_joinedます。残念ながら、Djangoはこれらのフィールドを両方ともdatetime.now()に初期化し、数マイクロ秒離れている可能性があります。

In [1]: u = User.objects.create(username="bla")

In [2]: u.date_joined - u.last_login
Out[2]: datetime.timedelta(0, 0, 23)

私が使用している現在のハック:ユーザーが少なくとも1回はログインしていると仮定します user.last_login - user.date_joined >= datetime.timedelta(seconds=1)

ユーザーがログインしたことがあるかどうかを確認するためのより良い方法はありますか?

4

4 に答える 4

4

新しいバージョンのDjango(> 1.8)の場合は、User.last_loginを使用する必要があります。これは、ドキュメントに記載されている内容です。

前回のログイン

ユーザーの最後のログインの日時。

Django 1.8で変更:ユーザーがログインしたことがない場合、このフィールドはnullになります。以前は、デフォルトで現在の日付/時刻に設定されていました。

于 2015-12-23T14:47:07.853 に答える
2

date_joinedとの両方が作成時に現在の日付に設定されていると言うとき、あなたが正しいと仮定します。last_login何らかの理由で、2つの割り当ての間に、顕著なデルタを作成するのに十分な時間が経過しています。

その場合は、@ LAKのアドバイスを受けて、pre_save(およびインスタンスのIDが0かどうかを確認)またはpost_save(およびパラメーターを確認)のいずれかを作成フィールドを手動createdで。と同じ値に設定できます。そこから、あなたの将来のデータはすべて、あなたが軽蔑しているように見える1秒のあいまいさから保存されます。last_loginNonedate_joined

あなたの既存のデータに関しては、あなたはあなたが持っているデータで最善の推測をするのに行き詰まっていると思います。あなたがしていると仮定するのは危険すぎるとは思いません。すべての新しいデータと同じになるようにクリーンアップする場合は、データベースを更新してlast_login値を設定するだけです。Southを使用している場合、これはデータ移行で行うのに十分簡単です。それ以外の場合は、新しいコード変更をデプロイした後に実行するスクリプトを作成するだけで済みます。

正直、少しずれているのは問題ではないと思います。アカウントが作成された時間枠内にユーザーがログインすることは人間的に不可能である可能性が高いと想定している限り、アカウントを強制的に追加するために大量の追加作業を追加する理由はほとんどないようです。完全一致。

于 2012-08-20T18:55:12.543 に答える
0

オブジェクトを使用しFてと比較last_logindate_joinedます。それらが等しい場合、ユーザーはログインしたことがありません(または、少なくとも最初のサインアップ後にログインしたことはありません。これは、判断できる最善の方法です)。

from django.db.models import F

User.objects.filter(last_login=F('date_joined'))

アップデート

まあ、それは私の環境ではうまく機能しましたが、2つが数マイクロ秒以上ずれている可能性があると思います。その場合、あなたの唯一の頼みは実際にそれぞれを手動でチェックすることだと思いますUser。より正確にする必要がある場合は、次のバリエーションを実行できますが、一般的に、カウントを最初に作成した日以降にログインしたことがないユーザーは、すべての目的と目的で「ログインしたことがない」と見なされる可能性があります。ちなみに、彼らはアカウントを放棄しました。

if user.date_joined.date() == user.last_login.date():
    # do something

より高い精度が必要な場合:

date_joined = datetime.combine(user.date_joined.date(), time(user.date_joined.hour, user.date_joined.minute))
last_login = datetime.combine(user.last_login.date(), time(user.last_login.hour, user.last_login.minute))
if date_joined == last_login:
    # do something

これにより、基本的に新しい日時オブジェクトが作成され、秒とマイクロ秒の違いがなくなります。確かに、ここでは1分の精度レベルで十分です。

于 2012-08-20T20:25:06.497 に答える
0

QuerySetこれは、サイトにログオンした、またはログオンしていないユーザーでフィルタリングできるソリューションです。

filter_user_has_used_site()andfilter_user_hasnt_used_site()関数は、をQuerySet含むで機能しauth.Userます。

およびは、という名前のフィールドを持つモデルのクエリセットで機能filter_resource_has_used_site()します。filter_resource_hasnt_used_site()ForeignKeyuserauth.User

mysqlでのみ機能しますが、他のデータベースエンジンをサポートするように簡単に作成できます。

from datetime import timedelta
from django.db import connection

MYSQL = "ABS(TIMESTAMPDIFF(SECOND,auth_user.last_login,auth_user.date_joined))"


def filter_resource_has_used_site(qs):
    """
    Takes a QuerySet of resources and returns a QuerySet only containing
    resources that has logged in to site at least once.
    """
    vendor = connection.vendor
    if vendor == 'mysql':
        # Force the orm to join to auth_user.
        qs = qs.filter(user__username__isnull=False)
        where = "".join([MYSQL, '>1'])
        return qs.extra(where=[where])
    else:
        raise NotImplementedError('Vendor type {} not supported.'.format(
            vendor))


def filter_resource_hasnt_used_site(qs):
    """
    Takes a QuerySet of resources and returns a QuerySet only containing
    resources that never logged in to site.
    """
    vendor = connection.vendor
    if vendor == 'mysql':
        # Force the orm to join to auth_user.
        qs = qs.filter(user__username__isnull=False)
        where = "".join([MYSQL, '<2'])
        return qs.extra(where=[where])
    else:
        raise NotImplementedError('Vendor type {} not supported.'.format(
            vendor))


def filter_user_has_used_site(qs):
    """
    Takes a QuerySet of users and returns a QuerySet only containing
    users that has logged in to site at least once.
    """
    vendor = connection.vendor
    if vendor == 'mysql':
        where = "".join([MYSQL, '>1'])
        return qs.extra(where=[where])
    else:
        raise NotImplementedError('Vendor type {} not supported.'.format(
            vendor))


def filter_user_hasnt_used_site(qs):
    """
    Takes a QuerySet of users and returns a QuerySet only containing
    users that never logged in to site.
    """
    vendor = connection.vendor
    if vendor == 'mysql':
        where = "".join([MYSQL, '<2'])
        return qs.extra(where=[where])
    else:
        raise NotImplementedError('Vendor type {} not supported.'.format(
            vendor))


def user_has_used_site(user):
    """
    Returns if a auth.user has logged into the site.
    """
    return abs(user.last_login - user.date_joined) > timedelta(seconds=1)
于 2014-02-19T10:32:54.497 に答える