Wagail one page with different content - python

I am new to Wagtail and python, so could apprectiate some help with my problem.
I have a web app (wagtail web site + rest api backend).
On my website I have 2 pages:
HomePage with list of accessible objects (e.g. photos)
PhotoPage with a detailed information on photo
What I want to achive:
When I click on photo on homepage I am redirected to the photopage
I fill the photopage with information I got from backend
And the photopage url is smth like this http://example.com/photo?id=12345
So, I want to
have 1 model for photopage
fill photopage based on a requested url (i.e. from homepage I redirect user to example.com/photo?id=12345 and it is filled with information on photo with id=12345)
I guess there should be some middleware to parse requested url to get the id and fill the page with info from API. Is there any standard solution to this issue?

Page objects (and any classes that inherit from Page) have a get_context method that can be used to add context pre-rendering of your templates.
from django.shortcuts import get_object_or_404
class PhotoPage(Page):
# your model definition ...
def get_context(self, request):
context = super(PhotoPage, self).get_context(request)
photo_pk = request.GET.get('id',None)
photo = get_object_or_404(YourPhotoModel,pk=photo_pk) # if no matching photo, return 404. You can do whatever you like instead :)
context['photo'] = photo
return context
Now in your photo template you can access your Photo model instance directly...
{{ photo.some_attribute }}
{{ photo.some_other_attribute }}

Related

Returning a filter result in a different page - Django

I've searched up but nothing seams to do the trick or be on point.
Let's say i have two websites on page A.html I have a filter (djnago_filter) and B.html is empty. If the user submits the search form he is redirected from page A.html to page B.html where the results are displayed with for loop.
How do I to that?
I was thinking about passing the data from query set to another view but there must be better solution to this.
There are several ways to store and display information on the different views(pages):
You could use the Sessions:
#views.py
#set the session key in the view A:
request.session['info'] = {'key', 'value'}
#get the session key in the view B:
info = request.session['info']
del request.session['info']
You could use Models with JSONField:
#app/models.py
#model to store information from page A
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User,
on_delete=models.DELETE,
related_name="info")
info = models.JSONField()
#views.py
#store data in the view A:
from app.models import MyModel
MyModel.objects.create(user=request.user, info={'key', 'value'})
#retrieve data in the view B:
info = MyModel.objects.get(user=request.user)
But actually, all depends on the logic that you intent to achieve. There are actually other methods like using async Ajax, React, WebSockets...
you can pass it as an HTML request parameter inside the url, for example, in your pageA template will be
to page B
and inside pageb view, you can take the filter from the request object
def page_b_view(request):
some_filter = request.GET.get('some_filter')

Django: Pass arguments in View and display on the page

Say, I've got 2 views in views.py: Fetching_information_view and Processing_view.
In Fetching_information_view I am fetching information which I am displaying to the user in the tabular format on the "home.html" page. That's all okay.
Now, I get a CSV URL for each row as well. I don't want that when the user clicks on the CSV URL it should open the CSV; instead, when the user clicks on it then it should go to the Processing_view and it should be served on a different HTML page, say "process.html".
CSV URL:
/some_bucket/some_csv_file.csv?AWSAccessKeyId=some_id&Expires=1234&Signature=some_signature
Desired URL:
http://example.com/process.html?file=some_bucket/some_csv_file.csv?AWSAccessKeyId=some_id&Expires=1234&Signature=some_signature
Now, how can I call Processing_view from the Fetching_information_view view and send the file information? It should process in the backend and display results on process.html.
This is the table I am showing on the homepage:
I've wrote sample code for views.py which I'm using:
def process_data(request):
# what should come here?
# Display in process.html
def home(request):
some_data = SomeTable.objects.filter(user = request.user)
args = {"some_data": some_data}
# display as table on home.html, including URLs it is carrying
return render(request, "home.html", args)
If you don't want to expose the URL of your CSV files, then don't add it (and also don't expose the URL parameters) to the context of your home view and template.
So assuming you've created a urlpattern named process_view for your process_data view, in your home.html template you can just use href="{{% url 'process_view' %}?id={{ id }}" to append the id of the object to your request's URL parameters.
Then in the process_data view, you can get this id by id = request.GET.get('id'), fetch the model with this id and reconstruct the CSV url and file parameters.

How do I make allauth's authentication available on my homepage URL?

So i've installed Django allauth to handle my login authentication. However I don't want a seperate URL for login. I want it to be available on my homepage via Javascript onclick (login box appears when you click a button/no page refresh). But the current allauth URL is located at '/accounts/login'. So as I said I need it located at '/'. How would I do this?
Here is my views.py:
def boxes_view(request):
...
search = request.GET.get('search')
posts = Post.objects.all().filter(category=1).order_by('-date')
if search:
posts = posts.filter(
Q(title__icontains=search) |
Q(content__icontains=search)
)
else:
posts = Post.objects.all().filter(category=1).order_by('-date')
context = {
'posts': posts,
}
return render(request, 'polls.html', context)
Can I pass it in as context or? How would it be done?
It sounds like you want a user to be able to log in using a modal from your homepage, or what you currently see when going to '/'
If so, you don't change the allauth login url. Instead change your javascript code for your login box to present the contents given here.
See also this answer.

Django url pk + slug page not found

I'm using django allauth for user authentication and so far I have been able to display user's page like this: account/1/trial/, where 1 is the pk number and trial is the username(unique), or like this: account/1/. In both cases everything works fine, but if I want to show only the username (account/trial/) in the url than I can't load the profile (accounts/profile/) page for the logged in user(404). Probably my profile function is wrong, how can I correct it so that the page will load normally as if using pk in urls.
urls:
(r"^(?P<pk>\d+)/(?P<slug>[\w.#+-]+)/$", DetailView.as_view(context_object_name='detail',slug_field = "username",model=User,template_name='account/user_detail.html'), name='detail_view'), #if I use this url the page loads correclty
(r"^(?P<pk>\d+)/$", DetailView.as_view(context_object_name='detail',slug_field = "username",model=User,template_name='account/user_detail.html'), name='detail_view'), # also with this url it works
(r"^(?P<slug>[\w.#+-]+)/$", DetailView.as_view(context_object_name='detail',slug_field = "username",model=User,template_name='account/user_detail.html'), name='detail_view'), #if I use only the slug the page does not load.
(r"^profile/$", views.profile, name="profile_view"), #this is the profile page url
and the profile page view:
def profile(request):
return render_to_response("account/profile.html",locals(),context_instance=RequestContext(request))
The string "profile" matches the regex for the slug-only username view, and since Django matches URLs in order, a request for the URL "profile/" will always go to that view instead. The simple solution is to move the profile URL above the other one.

Django dynamic page functionality and url

I have a some problem with routing in my django app.
The problem:
There is some dynamic website and site administrator can create pages with random urls. For example, he can create a news page with url "company/news" or "store/news". Or he can create the page with feedback form with url "feedback" or "user/feedback".
So, Django needs to catch this request and show appropriate news or feedback content for these pages. How can I route the user request to the appropriate view according to the requested page functionality?
You can create view that parses your URL and chooses strategy for different types.
# urls.py
...
url(r'^dynamic-view/(?P<dynamic_view_url>.*)/$', 'dynamic_view')
# views.py
def dynamic_view(request, dynamic_view_url):
url_parts = [p for p in dynamic_view_url.split("/") if p]
if "feedback" in url_parts:
return _view_for_feedback(request, url_parts)
elif "news" in url_parts:
return _view_for_news(request, url_parts)
else:
raise Http404

Categories