How do I separate user accounts in Django ? - python

I am using Django to create an app that allows recording of medical information however I am having problems with seperating the user accounts so currently all users see the same information entered. Anyone familiar with django knows how to set the proper permissions and roles and is willing to help a newby out?
I want the user to only access to the account the user creates and the records that the user create.
This is my github link
If you are able to to help I would really appreciate it.

If you want to list only the user's records in your /home . You only need to change the query in your home/views.py, from Identity_unique.objects.all() to Identity_unique.objects.filter(user=request.user)
class Identity_view(TemplateView):
def get(self, request):
form = Identity_form()
Identities = Identity_unique.objects.filter(user=request.user)
var = {'form': form, 'Identities': Identities}
return render(request, self.template_name, var)
Or if you want to filter objects in your Django Admin panel you should read this:
Django Documentation: ModelAdmin.get_queryset(request)

Create a custom user model with an extra field user_type.
https://github.com/samimsk/debatehub/blob/master/devdebatehub/UserApp/models.py
Implemented here.

Related

Need help understanding Django authentication code

Code from views.py:
from django.contrib.auth.decorators import login_required
#login_required
def index(request):
user = request.user
posts = Post.objects.filter(user=user)
I can't understand the inline #login_required. Why should we use this decorator?
And what about user = request.user? In this project, we hadn't created a model named user.
Please explain this to me. Thanks a lot!
In this code I can't understand inline #login_required Why should we use the decorator
The #login_required decorator does exactly what it says: it requires a user to log in when accessing the route associated with this view.
And user=request.user user ?? In this project, we hadn't created models named user.
Django defines a User model fore you.
For more details about the default authentication and authorization system, read the documentation. Googling something like "django login_required" gives a wealth of information.
The logic behind this function is to achieve that only the logged-in user has access to the posts he wrote himself: all http requests contain the id of the user: if he is not logged in, he is identified as anonymous, otherwise as user.
To get his identification, you call request.user and then pass it to the query to call his posts.
Therefore :
neither an anonymous user nor another user can get access to the full list of posts of a third user.

Django - How to differentiate between users in the database?

I'm building a Django server for my company and I'm still unfamiliar with some processes. I'm sure this is super simple, I'm just completely unaware of how this works.
How do I differentiate between user's data so it doesn't get mixed up?
If Jill is a user and she requests a page of her profile data, how do I not send her Jack's profile data, especially if there are multiple models invovled?
For example, the code in the view would look like this:
def display_profile(request)
profile = Profile.objects.get(???) # What do I put in here?
I understand that I can do:
def display_profile(request, user)
profile = Profile.objects.get(user_id=user)
But that's not my design intention.
Thank you in advance.
As documented
Django uses sessions and middleware to hook the authentication system into request objects.
These provide a request.user attribute on every request which
represents the current user. If the current user has not logged in,
this attribute will be set to an instance of AnonymousUser, otherwise
it will be an instance of User.
So in your case (notice field not being called user_id )
profile = Profile.objects.get(user=user)
In your Django view, you can access the current user with request.user.
So if you want to get a Profile instance matching your current logged in user, just do a query as follow:
profile = Profile.objects.get(user=request.user)
This assumes you have a user foreign key field (or OneToOne) in your Profile model.

Django not REST - API user registration

I have my first project as junior in my work. It is old (Django 1.8) and it is normal django framework... not REST.
It supports web, and mobile.
I have to create endpoint for mobile to create user.
I think it is not a problem (to create) but I want to make sure it will be save.
First of all I thought that I will create normal ModelForm (RegisterAPIForm based on model=User with full validation (I mean init all fields that are in "backend" not visible for user | cleaned_data for all fields | special overwriten method save() that in addition hashes password, and send email) and in Views I'll add something like this:
class RegistrationAPITestView(View):
def post(self, request):
form = RegistrationAPIForm(
request.POST
)
if form.is_valid():
form.save()
return JsonResponse({})
else:
#check errors and send error code back
Or I should do it other way, by using User object?
class RegistrationAPITestView(View):
def post(self, request):
#check if user does not exist
#password1 and password2 validation
user = User.objects.create()
user.name = request.POST['username']
user.set_password(request.POST['password'])
#init all fields that user can't choose like groups etc
user.save()
What do you think? Do I need ModelForm that I won't even render? It seems to be safer, but maybe I should check it other way? with User object?
Btw. Registration form already exists for web but there is a lot of "web" stuff that I don't need and I don't have to check and there is another method of saving password, so I believe I should create new one.
My code will be revieved in 2 weeks (senior vacations) but now I'm alone and want to do my best.
There is nothing wrong with the second option, but here is the problem that you as a junior should avoid. This line will make the server return a 500 error request.POST['username'] because python will throw a key error if the user doesn't provide the username, to fix just change to request.POST.get('username', 'value if doesn\'t exit') also make sure that everything is ready before create the user or you will have records in the database that wont be useful. Call validators to the password too and try to cover all possible scenario. Remember never trust the user

Django registration-profile - next step to a user profile

I have installed the django-registration app to my project. After a successful log in step, I am redirecting the user to localhost:8000/ - this is my default testing host and port. And I am displaying somewhere on the page, the username of the logged in user.
What I want to do now is that when I click the username some options like edit profile or change password will appear. My questions are the following:
Should I create another model (inside another new app) containing fields like profile photo, gender, birthday etc and add a foreign key to the User model from django.contrib.auth.models ? Or should I modify the model from django-registration to add some additional fields but which I do not ask for at registration phase and only update them later?
if I want my profile edit feature to be at /accounts/edit, which would be the best practice to do it? to edit the URLconf of my project and add a line like (r'^accounts/edit$',.....) just before (r'^accounts/', include('registration.backends.default.urls')), ?
I hope I made myself clear. I'm trying to figure out which would be the best approach before coding, as I am new to Django... Thanks
I find it's easier to decouple the profile table from the auth table. Just like you mentioned you can use a foreign key relationship to link that profile to the user. You can also apply a lambda inside of your profile table to automatically create a profile when a new user object is created.
Inside your template you can link to the profile page dynamically based on the current authenticated party by using
{% if request.user.is_authenticated %}
Update Profile
{% endif %}
user_profile being the name of your app which holds your user_profile table. That way when the request is made you use the regular expression for the current user id (similar to the polls example provided by django) to get the id number of the currently logged in user than inside the views you just query the database for that particular user.
views.py
def myView(request, user_id):
userProfile = UserProfile.objects.get(user.pk=user_id)
This is a high level example to give an idea of one way to accomplish it.

Multiple Instances of a django app, does django support this

I have written a simple feedback application in django. It's not particulairly complex, basically it allows authenticated users to write a shot message with a subject line and submit that message via a form. I then allows who are in a selected group to view user submitted feedback. In the future I may add more functionality but for now it does what I want.
Here comes my question, the site I'm building has multiple places where I would like to use the feedback app, for example I have a "what do you think of the site?" kind of page at /dev/feedback/ I also have one for customer support feedback at "/support/feedback/" Currently I have just copied the code from my mysite.apps.dev.feedback over to mysite.apps.support.feedback.
The problem is that this has now created two separate copies of the same code. Despite having just written the app the two versions are already starting to diverge which is annoying. My question is simply how do I create multiple instances of the same app in a django site with distinct database models?
Some resources I've found related but not helpful are https://docs.djangoproject.com/en/dev/topics/http/urls/ and Reversing namespaced URLs in Django: multiple instances of the same app The first page does not offer much on the issue and the second page provides somewhat cludgey and impractical solutions that seem to be both unrelated and more work than their worth. Is there a proper way to implement multiple instances of the same django app?
Single model approach
I'd personally try to keep this as one app and have a view that can handle being posted from multiple locations / tag them appropriately.
As S.Lott says, this is the way to go. I am providing alternatives if you're curious about methods to keep your code in one place in other situations.
For example, you could add a category field to your model, set up a single url conf which accepts an argument in the URL such as /(?P<category>\w+/feedback/$ and have the view simply tag the feedback with the appropriate category.
class MyForm(forms.ModelForm):
class Meta:
model = Feedback
def my_view(request, category):
form = MyForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
feedback = form.save(commit=False)
feedback.category = category
feedback.save()
return http.HttpResponse("Thanks for posting!")
return render(request, "mytemplate.html", {'form': form})
# urls.py
(r'^(?P<category>\w+)/feedback/$', 'my_view')
# user can visit dev/feedback or support/feedback and the feedback will be tagged appropriately
Abstract base class
Another solution is to build an abstract base class, then create subclasses for your distinct tables. That should solve the issue with your code getting out of sync.
You'd have a single abstract model (which has no tables) from which your "real" models in your separate apps would be based on.
Dynamically generated views
If you must have separate models, you could potentially write a dynamically constructed view.
def view_generator(model_class):
class MyForm(forms.ModelForm):
class Meta:
model = model_class
def my_view(request):
form = MyForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return http.HttpResponse("Thanks for posting!")
return render(request, "mytemplate.html", {'form': form})
return my_view
# urls.py
from foo import view_generator
(r'^my_first_feedback_form', view_generator(Model1))
(r'^my_second_feedback_form', view_generator(Model2l))
how do I create multiple instances of the same app in a django site with distinct database models?
You shouldn't.
You simply use the feedback app model in the other two apps with a simple from feedback.models import Feedback.
Then your support app can create, retrieve, update and delete Feedback objects.
Your dev app, similarly, can create, retrieve, update and delete Feedback objects because it imported the model.
That's all that's required: import.
Thanks Yuji Tomita for a very thorough answer, my final solution is derived very closely from his suggestion, but is different enough that I thought I would post it as another option if someone else runs into the same situation that I am in.
Firstly in my mysite.apps.feedback.models file I put
class Feedback( models.Model ):
subject = models.TextField( max_length=100 )
body = models.TextField( max_length=100 )
# Some other stuff here...
# Finally I used the suggestion above and created a field which I
# use to label each entry as belonging to a specific instance of the app.
instance_name = models.TextField( max_length=20 )
In my mysite.apps.feedback.views file I put
def save_message( request, instance_name ):
if request.method == 'POST':
form = FeedbackFrom( request.POST )
if form.is_valid():
form.instance.instance_name = instance_name
form.save()
return render("feedback/thanks.html")
else:
return render("feedback/submit.html", {'form':form })
else:
return render("feedback/submit.html",{'form':FeedbackForm()})
#user_passes_test( is_staff )
def all_messages( request, instance_name ):
messages = Feedback.objects.filter( instance_name = instance_name )
return render("feedback/view_all.html",{'feedback':messages} )
In my mysite.apps.dev.urls file I put
url(r'^feedback/', include('mysite.apps.feedback.urls'),
{'instance_name':'dev'}),
In my mysite.apps.support.urls file I put
url(r'^feedback/', include('mysite.apps.feedback.urls'),
{'instance_name':'support'}),
This will separate feedback messages by app instance. Note that my actual code is more complex but this should be good enough for anyone with a similar problem to get a solution up and running pretty quickly. Hope this is useful to anyone in a similar situation. Thanks again to Yuji Tomita for the suggestions upon which this solution is based.

Categories