我正在尝试在我的注册网站中实现共享。我希望用户能够在一段时间内(1天,1周等)共享页面,以便任何有特殊链接的人都可以访问该页面。这在Django中是否可行?
编辑:我的解决方案(基于Saurabh Goyal’s answer):
为models.py
添加新模型,如下所示:
class ShareKey(models.Model):
location = models.TextField() # absolute path
token = models.CharField(max_length=40, primary_key=True)
creation_date = models.DateTimeField(auto_now_add=True)
expiration_seconds = models.BigIntegerField()
data = PickledObjectField() # custom sharing data
(data
字段是可选的,需要django-picklefield)。
在views.py
中,添加如下的装饰器功能:
def allow_shares(view_func):
def sharify(request, *args, **kwargs):
shared = kwargs.get('__shared', None)
if shared is not None:
if '__shared' not in view_func.func_code.co_varnames[:view_func.func_code.co_argcount]:
del kwargs["__shared"]
return view_func(request, *args, **kwargs)
else: return login_required(view_func)(request, *args, **kwargs)
return sharify
除非页面是共享的,否则此装饰器允许视图需要登录。
@allow_shares
装饰您想要共享的任何视图。添加一个新的Exception子类SharifyError
,如下所示:
class SharifyError(Exception):pass
同样在views.py
中,添加一个视图来解析共享网址,如下所示:
def sharedPage(request, key):
try:
try:
shareKey = ShareKey.objects.get(pk=key)
except: raise SharifyError
if shareKey.expired: raise SharifyError
func, args, kwargs = resolve(shareKey.location)
kwargs["__shared"] = True
return func(request, *args, **kwargs)
except SharifyError:
raise Http404 # or add a more detailed error page. This either means that the key doesn’t exist or is expired.
向urls.py
添加网址,如下所示:
urlpatterns = patterns('',
# ...
url(r'^access/(?P<key>\w+)$', views.sharedPage, name="sharedPage"),
# ...
)
最后,添加URL以创建共享链接,并实现如下视图:
# in imports
from django.utils.crypto import get_random_string
def createShare(request, model_id):
task = MyModel.objects.get(pk=model_id)
key = ShareKey.objects.create(pk=get_random_string(40),
expiration_seconds=60*60*24, # 1 day
location = task.get_absolute_url(),
)
key.save()
return render(request, 'share.html', {"key":key});
(您的share.html
模板应该如下所示):
{% extends 'base.html' %}
{% block content %}
<h1>Sharing link created.</h1>
<p>The link is <a href="{{ base_url }}{% url 'taskShared' key.pk %}">{{ base_url }}{% url 'taskShared' key.pk %}</a>. It will be valid until {{ key.expiration_date|date:"l, N dS" }} at {{ key.expiration_date|time:"g:i a" }}.</p>
{% endblock %}
这将要求用户登录以查看已装饰的页面,除非他们输入了密钥。
答案 0 :(得分:0)
是的,您可以通过在dB中添加一个额外字段来实现这一点,该字段将代表所有人都可以访问页面的最后日期时间。然后每当有人访问它时,只需检查当前日期时间是否等于或等于该字段的值,如果是,则让他们访问,如果不是,则拒绝访问。
当用户发出使页面可访问的请求时,请创建特殊链接并相应地更新字段。
确保处理您在每次请求时生成的特殊链接的路由。
要使用键处理事物,您可以采取以下步骤 -
1)每当用户请求特殊链接时生成随机密钥
2)在db
中存储密钥和相应的最新访问日期时间3)假设您网页的主网址是'/ mypage /',而您的urls.py就是这样的 -
from django.conf.urls import patterns, url
from apps.myapp import views as myapp_views
# See: https://docs.djangoproject.com/en/dev/topics/http/urls/
urlpatterns = patterns(
'',
url(r'^mypage/$', myapp_views.MyPageView.as_view(), name='mypage'),
)
你添加了另一个网址,就像这样 -
from django.conf.urls import patterns, url
from apps.myapp import views as myapp_views
# See: https://docs.djangoproject.com/en/dev/topics/http/urls/
urlpatterns = patterns(
'',
url(r'^mypage/$', myapp_views.MyPageView.as_view(), name='mypage'),
url(r'^mypage/(?P<key>\w+)/$', myapp_views.MyPageView.as_view(), name='mypage_special'),
)
以上结果是网址'/ mypage / any_alphanumeric_key /'也会重定向到您的网页浏览。
4)在您的视图中,访问密钥,从dB获取该密钥的最新访问日期时间,如果有效,则授予访问权限,否则拒绝访问。