简体   繁体   中英

Share django page to user who does not have an account

I am trying to implement sharing in my registration-required website. I would like the user to be able to share a page for a certain duration of time (1 day, 1 week, etc.) so that anyone with a special link can access that page. Is this possible in Django?

EDIT: My solution (based on Saurabh Goyal's answer ):

  1. Add a new model to your models.py , something like this:

     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 

    (The data field is optional, and requires django-picklefield ).

  2. In your views.py , add a decorator function like this:

     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 

    This decorator allows a view to require a login, unless the page is shared.

  3. Decorate any views you want to be shareable with @allow_shares .
  4. Add a new Exception subclass, SharifyError , like this:

     class SharifyError(Exception):pass 
  5. Also in views.py , add a view to resolve the shared URLs, like this:

     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. 
  6. Add a url to urls.py , like this:

     urlpatterns = patterns('', # ... url(r'^access/(?P<key>\\w+)$', views.sharedPage, name="sharedPage"), # ... ) 
  7. Finally, add URLs to create a shared link, and implement the view like this:

     # 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}); 

(Your share.html template should look something like this):

{% 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 %}

This will require users to login to view the decorated pages unless they have entered a key.

Yes, you can do that simply by having one additional field in dB which will represent the last datetime till when page is accessible by all. Then whenever someone accesses it, just check if current datetime is before or equal to value of that field, if yes, let them access, if no, deny access.

When user makes request to make page accessible, create the special link and update the field accordingly.

Make sure to handle routing for special link you generate on every request.

Edit-

To handle things using keys, you can take following steps-

1) generate a random key whenever user requests for special link,

2) store the key and corresponding latest datetime of access for page in db

3) assuming main url for your page was '/mypage/', and your urls.py is something like this-

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'),
)

you add another url, something like this-

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'),
)

What above results in is that a url '/mypage/any_alphanumeric_key/' will also redirect to your page view.

4) In your views, access the key, fetch the latest datetime of access for that key from dB, and if valid, give access else deny access.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM