Django rest framework best practices - django

I was wondering what would be the best approach . I've been agonizing on what is the best way to accomplish a given task. It is a project with a react frontend and django rest framework backend. I am working on the backend with the django rest framework .
Task:
To query a user by their phonenumber which is stored as the username field.
To add a user to a profile model and add an extra field which is required by the profile model
To create the new profile with the user as the profiles user .
e.g
Profile Model:
User - ForeignKey
ExtraField - Charfield
My question is which of these solutions is better .
Should I build a url like this : domain/users/{phonenumber} and post the Extra field
and query the user like this.
def get_object(self):
return get_object_or_404(User,username=self.kwargs['phonenumber'])
user= get_object()
or
Should I post both the phonenumber and the extrafield and query the user from the backend like this.
user = get_object_or_404(User,username=request.data.get('phonenumber'))
both work but which would be the best practice if it even matters at all.

If you just starting a django project the best way would be to create a custom user model with only fields you need for your user.
See docs here.

Related

django_currentuser alternatives or how to get current user in Models.py

I have 2 Models in my django models.py.
I need to get data from model2 to model1, but I don't need to store it anywhere in the model1 fields. I found #property of django and implemented that. My issue was that I need to get who the user is using request.user, which is not possible in models.py
So how can I access user in django models? Is there any other packages? or is there any inbuilt django way which I haven't thought about?
I searched and got a package called django-currentuser , unfortunately i'm using Django 4 which doesn't have a support.
I didn't get exactly what's your problem.
if you want to get the current user in django,this should be handled in your views like:
def View(request):
user = request.user
and if the other model that you got data from have any field connected to User like:
user = models.Foreignkey(User,...)
you can easily achive the user...
please describe more...

How do i implement both built-in django auth and third party social-auth in my application?

I using django from last 4-5 months and recently started learning django-rest-framework and I'm confused about proper authentication system,
Actually I am trying to build an application mostly using REST API because my
client can be both browser and Android,
so I need an authentication system in which user can sign up using both django
built-in auth(django.contrib.auth.model.User) as well as third-party social
authentication(Google, Facebook, etc..).
Now, I'm confused about how do I create my database, because when ever i'll create
a table/model lets say a 'Book', then this model would need a foreign key to the user model and here user can be both 'django.contrib.auth.model.User' and a user signed-up using third party auth,
So how I will refer to User in foreign key Field of my models?
And I have also decided to customize django's buit-in auth because i want
user to login using their email not username.
class Book(models.Model):
title = models.CharField(...)
author = models.ForeignKey(?) ? Here, how do i refer to both
'django.contrib...User' and users signed-up
using thrid-party auth.
Let me elaborate on your question.
First of all: You're lucky. There's an (almost) out of the box version for your problem.
For social and normal authentication and registration, including email verification etc. you can rely on django-allauth:
https://github.com/pennersr/django-allauth
django-restauth provides a restful platform built on top of all-auth, so that you don't even have to start building your auth rest api from scratch:
https://github.com/Tivix/django-rest-auth
When it comes to your db schema, there are a few options. You could go ahead and build your own authentication system, which, in my opinion, is overkill.
Rather more, I would implement a profile model, which has a OneToOne relationship to the User model from django.contrib.auth.models.User as described in this chapter of the Django docs.
Your models (of course in separated apps) would look like this:
from django.contrib.auth.models import User
from django.db import models
#other imports
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
books_read = models.IntegerField(default=0)
books_recommended = models.IntegerField(default=0)
class Book(models.Model):
title = models.CharField(...)
author = models.ForeignKey('UserProfile', related_name='books')
Another question you will run into is how to update and/or display those nested relations in your serializers.
This FAQ article from the django-restauth docs and this chapter of the official django-rest_framework docs will get you jumpstarted.
Best,
D

Exposing a many to many field using Django REST Framework?

I'm creating an event following/signup system that uses Django REST Framework and can't figure out how to properly set this up.
In my events model I have:
followers = models.ManyToManyField(get_user_model(), related_name='following')
Ideally, an authenticated user could use a POST or PATCH to add or remove themselves from the followers record for a given event. Though I'm not really sure what the best way to do that would be.
My current thinking would be to create a serializer that only exposes the followers field, then create an APIView using that serializer with login in the get and post/patch methods to add or remove the specific user.
I'm getting the feeling that this is over-complicating things though. Is there an easier way to do this?
What do you think about using a 'through' model for the M2M relation?
I mean:
class Follower(...:
user = FK user
event = FK event
...
followers = models.ManyToManyField(get_user_model(), through=Follower ...)
...
In this case you are able to create quickly a model serializer and a generic view for the model Follower. In order to add or remove a user to an event you just send POST or DELETE requests to this resource

Django authentication with custom model User

For my needs builtin model User is not enough... So I have my own model UserProfile and I want make authentication on site through this model (UserProfile does not inherit from User model and not related to it at all).
My Model:
class UserProfile(models.Model):
password = models.CharField(max_length = 40)
email = models.EmailField(max_length = 72, unique = True)
## Add this so that you can use request.user.is_authenticated
def is_authenticated(self):
return True
But builtin authentication uses model User.
So I want to understand how can I change that, so authentication use my model UserProfile with all auth features???
A good tutorial would be great!
(Step by step in views, models and authentication)
PS: I know I can store extra data in other model but I don't want that
Here's an even more extreme example but illustrates that what you want to do can be done. The author not only replaces the User model which the authentication backend uses but also uses SQLAlchemy instead of the Django ORM. http://tomforb.es/using-a-custom-sqlalchemy-users-model-with-django
The main point is that you need to write your backend authenticate and get_user methods to retrieve your custom User model. If you want to also support permissions you would need to write has_perm.
I used this article and it worked good enough for me, hope it can be useful for you.
Sultan

Extending the User model in django

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
When it comes to extending the User model, the above article list two methods: the old way (ForeignKey) and the new way (User model with inheritance). But at the same time, this article dates back to Aug 2008.
I am using Django's development version.
Would you recommend Extending the Django User model with inheritance or by using ForeignKey?
I read in a couple of posts that extending django.contrib.auth.models.User is not recommended, so I will not be looking at that.
AFAIK, the cleaner approach - if this can fit in your project architecture - is to have a distinct user profile model, and use the AUTH_PROFILE_MODEL setting to link it up to the Django User model.
See the Django Doc about storing additional information for Users
Dominique Guardiola is right. Use the AUTH_PROFILE_MODEL. James Bennett reiterated this in his 'Django in Depth' talk. http://www.youtube.com/watch?v=t_ziKY1ayCo&feature=related around 1hr:37mins.
Decide on the application where we want to house our user's profile, let's call it BngGangOfFour.
Define a Model class, lets name it UserProfile for clarity, and give it the extra field(s) we desire.
BngGangOfFour/models.py
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User) #notice it must contain a 1 to 1 field with the auth user.
last_ip_address = models.CharField(max_length=20, default="")
Edit settings.py to designate our newly created model as the user profile.
settings.py
....
AUTH_PROFILE_MODULE = 'BngGangOfFour.UserProfile' #not case sensitive.
....
Access the profile directly off the user objects.
BngGangOfFour/views.py
....
def index(request):
if request.user.get_profile().last_ip_address = "127.0.0.1":
print("why hello me!")
return render_to_response('index.html', locals(), context_instance=RequestContext(request))
Sip a cold beer and call it a day.
The only time you can cleanly get away with extending User via inheritance is if you're writing an auth backend which will return an instance of the appropriate model instead.