i am using djoser's create token end point to login user but i am getting following error.
I have tried google search but could not find any useful answer.
UPDATE
I have customized user model to add an extra field while registering user.
here is my models.py
from django.db import models
from custom_user.models import AbstractEmailUser
class UserProfile(AbstractEmailUser):
account_address = models.CharField(max_length=100, blank=True)
name = models.CharField(max_length=30, blank=True)
and this is my serializer.py
from djoser.serializers import UserCreateSerializer as BaseUserRegistrationSerializer
from rest_framework import serializers
class UserRegistrationSerializer(BaseUserRegistrationSerializer):
advertisements = serializers.HyperlinkedRelatedField(many=True, view_name='advertisement-detail', read_only=True)
class Meta(BaseUserRegistrationSerializer.Meta):
fields = ('id', 'email', 'advertisements', 'name', 'account_address', 'password')
and urls.py
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
urlpatterns = [
url(r'^account/', include('djoser.urls')),
url(r'^account/', include('djoser.urls.authtoken'))
]
Related
This question seems to be asked before but none of the answers I came across solve my issue.
I'm getting the following error when I try running the server with python manage.py runserver:
django.core.exceptions.ImproperlyConfigured: The included URLconf 'tutorial.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.
The error goes away if I change models.py so that my Item class does not extend models.Model.
These are the relevant files:
models.py
from django.db import models
from django.contrib.auth.models import User
class Item(models.Model):
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
price = models.DecimalField(decimal_places=2)
def __str__(self):
return self.name
serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User, Group
from .models import Item
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('url', 'name')
class ItemSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Item
fields = ('url', 'name', 'owner', 'price')
views.py
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from .serializers import UserSerializer, GroupSerializer, ItemSerializer
from .models import Item
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
class ItemViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows items to be viewed or edited.
"""
queryset = Item.objects.all()
serializer_class = ItemSerializer
urls.py
from django.urls import include, path
from rest_framework import routers
from tutorial.quickstart import views
router = routers.DefaultRouter()
router.register('users', views.UserViewSet)
router.register('groups', views.GroupViewSet)
router.register('items', views.ItemViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
I am having my models.py file defined as below:-
from django.db import models
from django.contrib.auth.models import User
class Custom_User(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
mobile = models.CharField(max_length=20)
REGISTRATION_CHOICES = (
('Learner', 'Learner'),
('Trainer', 'Trainer'),
)
primary_registration_type = models.CharField(max_length=15, choices=REGISTRATION_CHOICES)
def __str__(self):
return self.user.email
As you can see that my Custom_User model uses Django's User model as its foreign Key.
For the above model I have defined my serialziers.py file like this:-
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import *
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email')
class Custom_UserSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
class Meta:
model = Custom_User
fields = ('__all__')
Now I am using this serializers in my viewsets like below:-
from django.contrib.auth.models import User
from rest_framework import viewsets
from .serializers import *
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
class Custom_UserViewSet(viewsets.ModelViewSet):
queryset = Custom_User.objects.all()
serializer_class = Custom_UserSerializer
class TrainerViewSet(viewsets.ModelViewSet):
queryset = Custom_User.objects.filter(primary_registration_type="Trainer")
serializer_class = Custom_UserSerializer
class LearnerViewSet(viewsets.ModelViewSet):
queryset = Custom_User.objects.filter(primary_registration_type="Learner")
serializer_class = Custom_UserSerializer
And Finally inside my urls.py file I register them as below:-
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'users', api_mailing_list_views.UserViewSet)
router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet)
router.register(r'trainers', api_mailing_list_views.TrainerViewSet)
router.register(r'learners', api_mailing_list_views.LearnerViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', mailing_list_views.index, name='index'),
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
As I was expecting the urls list to be like below in my browser:
{
"users": "http://localhost:8080/api/users/",
"custom_users": "http://localhost:8080/api/custom_users/",
"trainers": "http://localhost:8080/api/trainers/",
"learners": "http://localhost:8080/api/learners/"
}
But what i get instead is a list of urls like this:-
{
"users": "http://localhost:8080/api/users/",
"custom_users": "http://localhost:8080/api/trainers/",
"trainers": "http://localhost:8080/api/trainers/",
"learners": "http://localhost:8080/api/trainers/"
}
However I am not getting any errors or if I visit the following url:-
http://localhost:8080/api/learners/
which is not showing up in the urls list I still get the filtered list of learners in JSON format.
Thanks for the help in advance.
you need to provide basename during router register as all of them actually from same custom_user model.
router = routers.DefaultRouter()
router.register(r'users', api_mailing_list_views.UserViewSet, basename='users')
router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet, basename='custom_user')
router.register(r'trainers', api_mailing_list_views.TrainerViewSet, basename='trainers')
router.register(r'learners', api_mailing_list_views.LearnerViewSet, basename='learners')
Django-rest-framework's router tries to identify the viewset by its model/queryset, since both viewsets use the same model things most likely get mixed up.
From the documentation:
If unset the basename will be automatically generated based on the queryset attribute of the viewset, if it has one. Note that if the viewset does not include a queryset attribute then you must set basename when registering the viewset.
Try providing a basename to the router:
router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet, basename='custom_users')
router.register(r'trainers', api_mailing_list_views.TrainerViewSet, basename='trainers')
router.register(r'learners', api_mailing_list_views.LearnerViewSet, basename='learners')
I try to create a new user (django user) via POST with
serializers.py
from rest_framework import serializers
from .models import *
from django.contrib.auth.models import User
class UsuarioSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email',
'password')
views.py:
class Registrar(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = UsuarioSerializer
urls.py:
from django.urls import path, include
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register('usuarios', views.UsuarioViewSet)
router.register('tecnicos', views.TecnicoViewSet)
router.register('pedidos', views.PedidoViewSet)
router.register('mispedidos', views.PedidoMiUsuarioSet)
router.register('registrar', views.Registrar, base_name = 'registro')
urlpatterns = [
path('', include(router.urls))
]
When i make a post i get this error:
UNIQUE constraint failed: auth_user.username
This works if i change the model User to Usuario...
Models.py:
class Usuario(models.Model):
email = models.EmailField(max_length=70, blank=True, null=True, unique=True)
password = models.TextField()
def __str__(self):
return self.email
But i need to use the User model from django
The username field in the user model is required.
This is why you must use this field in create operations.
Email address is not mandatory by default.
It happens on Django create user via a unique user username.
I am using djoser for auth purposes. I want to customize the create user end point of djoser. I have a User app. Here is my User model
from django.db import models
class User(models.Model):
email = models.CharField(max_length=100, blank=False)
name = models.CharField(max_length=100, blank=False)
last_name = models.CharField(max_length=100, blank=False)
account_address = models.CharField(max_length=30, blank=False)
password = models.CharField(max_length=100, blank=False)
and here is my serializer
from rest_framework import serializers
from User.models import User
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'id', 'email', 'name', 'last_name', 'account_address', 'password')
and my User.urls.py looks like following
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet
router = DefaultRouter()
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^account/', include('djoser.urls')),
]
and project's url.py is follwing
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^users/', include('User.urls')),
url(r'^advertisements', include('advertisements.urls')),
url(r'^account', include('wallet.urls')),
]
but i am unable to create user with customized model instead when i go to user/account/create i see djoser's default create user view. Anybody please tell where I am doing wrong. Thanks :)
Having in mind that you have set the AUTH_USER_MODEL to your User model.
Just import the Djoser User Registration Serializer And override it.
from djoser.serializers import UserCreateSerializer as BaseUserRegistrationSerializer
class UserRegistrationSerializer(BaseUserRegistrationSerializer):
class Meta(BaseUserRegistrationSerializer.Meta):
fields = ('url', 'id', 'email', 'name', 'last_name', 'account_address', 'password', )
You can also override other things in the serializer like create and update methods in case if you want to customize it.
And in settings.py
DJOSER = {
...
'SERIALIZERS': {
'user_create': 'yourapp.serializer.UserRegistrationSerializer'
}
...
}
For me, I wanted to write a custom create method and it worked when I override user_create_password_retype and used mine since this is internally using the UserCreateSerializer from djoser
DJOSER = {
...
"SERIALIZERS": {
"user_create": "account.serializers.user_serializer.CustomUserCreateSerializer",
"user": "account.serializers.user_serializer.CustomUserSerializer",
"user_create_password_retype": "account.serializers.user_serializer.UserCreatePasswordRetypeSerializer",
}
...
}
Other settings -
AUTH_USER_MODEL to your custom User model.
I am new to Django Rest Framework and am struggling to get my serialisations to work correctly for a foreignkey relationship between two models. I have tried to reduce my setup down to be as simple as possible but I still can't understand how it is supposed to work. I am trying to use HyperlinkedModelSerializer so (from the docs) 'that it uses hyperlinks to represent relationships'. When I try to visit the url for either the list or detail view for {model X} on the test server I get:
'Could not resolve URL for hyperlinked relationship using view name
"{model Y}-detail". You may have failed to include the related model
in your API, or incorrectly configured the lookup_field attribute on
this field.'
What am I doing wrong?
My models:
from django.db import models
class Project(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()
class ProjectPhoto(models.Model):
project = models.ForeignKey(
Project, related_name='photos', on_delete=models.CASCADE
)
image = models.ImageField()
caption = models.CharField(max_length=100)
date_added = models.DateTimeField(auto_now_add=True)
My serializers
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Project
fields = ('name', 'description', 'photos')
class ProjectPhotoSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ProjectPhoto
fields = ('image', 'caption', 'date_added', 'project'))
My views:
from rest_framework import viewsets
from projects.models import Project, ProjectPhoto
from projects.serializers import ProjectSerializer, ProjectPhotoSerializer
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all().order_by('name')
serializer_class = ProjectSerializer
class ProjectPhotoViewSet(viewsets.ModelViewSet):
queryset = ProjectPhoto.objects.all().order_by('date_added')
serializer_class = ProjectPhotoSerializer
EDIT:
My urls:
from django.conf.urls import url, include
from rest_framework import routers
from projects import views
router = routers.DefaultRouter()
router.register(r'^projects', views.ProjectViewSet)
router.register(r'^project-photos', views.ProjectPhotoViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
]
these are then added in my main app urls.py file. I don't think this is problem as if I change the serializer to ModelSerializer then everything works fine.
I think your problem is in your urls.py file, see the code and picture
rest/urls.py file
from django.conf.urls import url, include
from rest_framework import routers
from .views import ProjectViewSet, ProjectPhotoViewSet
router = routers.SimpleRouter()
router.register(r'project', ProjectViewSet)
router.register(r'project-photo', ProjectPhotoViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
]
Principal urls.py file:
from django.conf.urls import url, include
from django.contrib import admin
from rest import urls as urls_rest
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^rest/', include(urls_rest)),
]
and other option, try to use this code in your serializers.py file:
from rest_framework import serializers
from .models import Project, ProjectPhoto
class ProjectPhotoSerializer(serializers.ModelSerializer):
class Meta:
model = ProjectPhoto
fields = ('image', 'caption', 'date_added', 'project')
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ('name', 'description', 'photos')
depth = 2
You have 3 options to use serializers (see picture below)