How to make page content Dynamic with Flask? - python

I have a database which contains more than table one of them authors and their names, jobs, social accounts, etc.
I need to make a static page template and a route for that page so if anybody clicks on that author name in the site, take all of his information's from the database table and showing them on the page.
In a different way, i need to make a function to handle the request if anybody clicked on that author to now more about him, thus, i have a different request every time including a different author .
I can do that line by line for each on of them but it sounds bad, because i don't want to end up with 1000 lines of code, there is alot of them out there inside the table .
Please any way to do that in clear way, as always any help would be really appreciated :) .

For communication with the base use:
http://flask-sqlalchemy.pocoo.org/2.1/
for templete Jinja2
Declaring Models base
http://flask-sqlalchemy.pocoo.org/2.1/models/
Sample code
#app.route('/author/<username>')
def show_user(username):
user = User.query.filter_by(username=username).first_or_404()
name = user.name
last_name = user.last_name
adres = user.adres
return render_template('show_user.html', user=user, name=name, last_name=last_name, adres=adres)

Related

django URLs MultipleObjectsReturned error

I am making a simple webapp with Django. A user can have a profile, and under that profile create a blog post.
For example:
"path('profile/<int:pk>/',profile, name='profile')"
Returns the URL
"http://127.0.0.1:8000/profile/1/"
A user can then write blog posts which have the name in the URL
Example:
path('profile/<int:pk>/blog/<str:name>',Blogs, name='Blogs'),
Returns the URL
"http://127.0.0.1:8000/profile/1/blog/HelloWOrld"
However, IF two different users both name their blogs the same exact name, i get a 'MultipleObjectsReturned' Error.
I thought that by having the user PK earlier in the URL it would ensure that it would be unique, even if two blogs were called the exact same thing.
Views.py
def Blog(request, pk, name):
blog = Restaurant.objects.get(name=name)
user = CustomUser.objects.get(pk=pk)
if not user.id == request.user.pk:
raise PermissionDenied()
else:
context = {
'user': user,
'blog': blog,
}
return render(request, 'blog/blogs.html',context)
IS there any way to work around this without using the PK of the blog as well?
And if anyone could explain why my logic was wrong and it wasn't working in the first place.
Thanks.
You need to make sure you get the blog of that name of that user. I don't know exactly how your blog models look, but it's going to be something like
user = CustomUser.objects.get(pk=pk)
blog = Restaurant.objects.get(name=name, user=user)
And on the model, use the 'unique_together' property to ensure that the combination of user and blog name are unique, otherwise these URLs aren't going to work. Having the name completely unique as in George's answer isn't necessary and would mean that users couldn't create blog posts with titles already made by another user.
You need to make name field unique, and use SlugField for this if you want to use clean url:
class Restaurant(models.Model):
name = models.CharField(unique=True, ...)
slug = models.SlugField(unique=True, ...)
...

I want to add costume field after django social app login

Hi I am php developer new to python/django
I'm creating a social login with django using 'social-auth-app-django' library and i followed following tutorial to implement it.
https://simpleisbetterthancomplex.com/tutorial/2016/10/24/how-to-add-social-login-to-django.html
Its working fine but i also need to add costume files in database which will be in different table but it will be get added when new user is created.
I have extended the user table as following
from django.contrib.auth.models import User
class NewsCreator(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
CreatorLastLogs= models.CharField(max_length=100)
CreatorLogs= models.CharField(max_length=100)
and i want to add data to these fields when a new user is created or when existing user logins. I tried going through documentation but could not found any thing that is related to code extension/customisation etc. Thanks in advance
Hi i have found answer to this so i'm posting for people who will stumble upon this post later.
django social provides pipeline to extend their code, and we just have to extend this pipeline
for this in your setting.py file post following list(all in this list are default pipeline methods which gets called except for last one).
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
'newsapp.pipeline.save_profile'<-- this is your method
)
create a file in your app with name pipeline.py and name of method is to be provided in list above like last string in list (newsapp is name of my app provide your appname)
in your pipeline.py file
def save_profile(backend, user, response, *args, **kwargs):
if NewsCreator.objects.filter(user_id=user.id).count() == 0 :
newsCreator = NewsCreator.objects.create(user=user)
//your logic for new fields
newsCreator.save()
if you have any other query regarding django-social you can refer
https://github.com/python-social-auth/social-docs
its detail documentation

Creating a log of all pages visited by the user

I am creating this functionality with a Django application I have. I want to log all pages the user visits and display it to him.
I am using a middleware to achieve it.
class LoggingMiddleware:
"""
Class used to register and fetch pages where the user has been visiting.
"""
def process_template_response(self, request, response):
if request.user.is_authenticated():
UserHistory.objects.create(user=request.user, page_name=request.path, url=request.path)
if response.context_data:
response.context_data['user_history'] = UserHistory.objects.filter(user=request.user)
return response
I want to name these UserHistory entries in the database, instead of just set the url as the name (as it i s now).
I have though of adding a variable to all views I have, in a way that the request object has something like request.page_name.
Can someone think of a better way to do it?

Creating two separate registration forms in Web2py?

So I want to create two registration forms side by side. One for users and other for employees. So basically the index page will have something like "Click here if you are a user" and "Click here if you are an employee". It will redirect to the appropriate registration page. I want the user registration to be just like how the built in web2py registration is. For the employee registration I want the following fields:
Name 2. Store Name 3. Store Type 4. Zip Code
I am really new to web2py so not sure how to implement this. Could someone please tell me how I should go about creating a registration.py model for this? Also I want the index to redirect to these two links as appropriate:
[app]/user/register
[app]/employee/register
Also what would my controller file look like? Would I need a separate controller for user and the employee?
Your question is not quite clear. Do you want to show two forms side by side OR do you want to redirect to the appropriate registration page?
Let's assume you opt for the second option as you described in your question. I'm also assuming that for whatever reason, employees and users are not the same as i understood from your question.
First create the employee table in models:
STORE_TYPE = ['Department store', 'Discount store', 'Warehouse store', 'Mom-And-Pop', 'Boutique']
db.define_table('employee',
Field('first_name'),
Field('last_name'),
Field('store_name'),
Field('store_type', requires=IS_IN_SET(STORE_TYPE)),
Field('zip_code'),
auth.signature)
Then in the controller just ask the user if she is an employee or user:
def index():
form = SQLFORM.factory(Field('user_or_employee', requires = IS_IN_SET(['user', 'employee']))).process()
if form.accepted:
if form.vars.user_or_employee == 'user':
redirect(URL('user/register'))
elif form.vars.user_or_employee == 'employee':
redirect(URL('employee_register'))
return locals()
If the user is a 'user' then you'll redirect them to the user/register as wished. if they are an 'employee' then redirect them to index/employee_register
def employee_register():
form = SQLFORM(db.employee)
if form.process().accepted:
redirect(URL('welcome')) # or whatever function you wish...
return locals()
From there you can take it by yourself.
Don't forget to create the views. For index and for default/employee-register.html. In both views you should include the forms you've created, something like that:
{{extend 'layout.html'}}
<h2>Please Register to Continue</h2>
{{=form}}

django: keep each users data separate

I am trying to workout how / the best, most secure way to keep a user's data separate within a django site that I need to write.
Here is an example of what I need to do...
example app ToDoList
Using django contrib.auth to manage users / passwords etc, I will have the following users
tom
jim
lee
There will be a ToDo model (in my real app there will be additional models)
class ToDo(models.Model):
user = models.ForeignKey(User)
description = models.CharField(max_length=20)
details = models.CharField(max_length=50)
created = models.DateTimeField('created on')
The issue that I am having - and may be over thinking this: How would this be locked down so tom can only see Tom's todo list, lee can only see his todo list and so on...
I have seen a few posts stating that you could use filter in every query, or use urls, so the url could look like www.domain.com/username/todo
But either way I am not sure if this is the right way / best way, or bonkers in terms of stopping users seeing each others data
cheers
Richard
One approach is to filter the ToDo items by the currently logged in user:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from your_app.models import ToDo
#login_required
def todos_for_user(request):
todos = ToDo.objects.filter(user=request.user)
return render(request, 'todos/index.html', {'todos' : todos})
This locks down the view for authenticated users only, and filtering by the logged in user from the request, another user, even if logged in, can't access another user's ToDo records. Hope that helps you out.
Make url like www.domain.com/username/todo is one way to implement it, but it doesn't guarantee you achieve security.
What you should do keep your user's login information in a session data after user login, and every time you check certain view,
check whether that particular user has right to see this view.
using user's login info (ID, or username) when querying user's Todo list.
And I guess this link will help you to do your job.
Sessions, Users, and Registration.

Categories

Resources