When I access the base URL of http://127.0.0.1:8000/ I get the following error
ImproperlyConfigured at /
Could not resolve URL for hyperlinked relationship using view name "wallet-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
When I try to access the admin URL it works fine but when I access my data URL which is http://127.0.0.1:8000/wallets I get a 404 error page not found?
This is my serializers.py file
from rest_framework import serializers
from .models import Wallet
class WalletSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Wallet
fields = ('__all__')
My views.py file is the following
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import WalletSerializer
from .models import Wallet
#api_view(['GET'])
def getData(request):
queryset = Wallet.objects.all()
serializer = WalletSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)
This is my Models.py file
from django.db import models
class Wallet(models.Model):
raddress = models.CharField(max_length=60)
def __str__(self):
return self.raddress
I was using a simple class in my views.py file instead of 'GET' functions which I am doing now and I was also using routers in my urls.py file but I removed all that so I could create CRUD functions but I face this problem now
Related
I am writting an application in Django that uses the Django Rest framework. A GET request to the API URL works, but when I add a query to it, such as '?id=1845' it does not actually perform a query, it still returns the full list of results.
In the below code, I am trying to query the 'Indicator List'
views.py
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import IndicatorSerializer
from data_platform.models import Indicator
#api_view(['GET'])
def apiOverview(request):
api_urls = {
'Indicator List':'/indicator-list/',
'Indicator Detail':'/indicator-detail/<str:pk>/',
}
return Response(api_urls)
#api_view(['GET'])
def indicatorList(request):
indicators = Indicator.objects.all()
serializer = IndicatorSerializer(indicators, many=True)
#filterset_fields = ('id')
#filter_backends = [DjangoFilterBackend]
return Response(serializer.data)
#api_view(['GET'])
def indicatorDetail(request, pk):
indicators = Indicator.objects.get(id=pk)
serializer = IndicatorSerializer(indicators, many=False)
return Response(serializer.data)
urls.py
from django.urls import include, path
from . import views
urlpatterns = [
path('', views.apiOverview, name="api-overview"),
path('indicator-list/', views.indicatorList, name="indicator-list"),
path('indicator-detail/<str:pk>/', views.indicatorDetail, name="indicator-detail"),
]
serializers.py
from rest_framework import serializers
from data_platform.models import Indicator
class IndicatorSerializer(serializers.ModelSerializer):
class Meta:
model = Indicator
fields = '__all__'
I figured it out! I had to use a class view rather then a function view
class indicatorList(generics.ListAPIView):
queryset = Indicator.objects.all()
serializer_class = IndicatorSerializer
filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
filter_fields = ('id',)
and add 'django_filters', to INSTALLED_APPS
I am using Django 3.0 djangorestframework==3.11.0. I have created a task update view and passing the pk to url. The problem is - Although I have set the serializer instance to the model object I want to update. The serializer instance is not showing up.
models.py
from django.db import models
# Create your models here.
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
def __str__(self):
return self.title
serializers.py
from rest_framework import serializers
from .models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.apiOverview, name='api-overview'),
path('task-list/', views.taskList, name='task-list'),
path('task-detail/<str:pk>/', views.taskDetail, name='task-detail'),
path('task-create/', views.taskCreate, name='task-create'),
path('task-update/<str:pk>/', views.taskUpdate, name='task-update'),
]
views.py
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Task
from .serializers import TaskSerializer
#api_view(['POST'])
def taskUpdate(request, pk):
task = Task.objects.get(id=pk)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
expected behavior on url http://localhost:8000/api/task-update/4/
actual behaviour on http://localhost:8000/api/task-update/4/
as you can see the content field is empty but I want the already associated json to be shown there with pk = 4.
[Error][1]
AssertionError at /api/client-details/ Expected view Client_view to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly. Request Method: DELETE Request URL:
http://127.0.0.1:8000/api/client-details/ Django Version: 2.2.6 Python Executable: C:\Users\AravindManoj\PycharmProjects\Client\venv\Scripts\python.exe Python Version: 3.7.4 Python Path:
['C:\\Users\\AravindManoj\\PycharmProjects\\Client\\Client',
'C:\\Users\\AravindManoj\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip',
While using Generic view in Django it Showing Error while using DELETE function.Please anyone give me the syntax of generic views in model set i didnt find any problem but no Delete function
Views.py
from django.http import Http404, HttpResponse
from rest_framework import viewsets, status, generics
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ClassSerializer
from .models import Client
class Client_view(viewsets.ModelViewSet, generics.RetrieveUpdateDestroyAPIView):
queryset = Client.objects.all().order_by('-Name')
serializer_class = ClassSerializer*
lookup_fields = ['Name', 'UserName', 'Mobile', 'Email', 'Address']
urls.py
from rest_framework import routers
from .views import Client_view
router = routers.DefaultRouter()
router.register('', Client_view)
urlpatterns = router.urls
models.py
from django.db import models
class Client(models.Model):
Name = models.CharField(max_length=15)
UserName = models.CharField(max_length=15)
Email = models.CharField(max_length=20)
Mobile = models.CharField(max_length=10)
Address = models.CharField(max_length=20)
serializer.py
from rest_framework import serializers
from .models import Client
class ClassSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Client
fields = ['Name', 'UserName', 'Email', 'Mobile', 'Address']
You have used lookup_fields which is not any built-in feature. Try to do it with a custom mixin like described here in the docs.
When using a ViewSet (in your case you are using a ModelViewSet) the view requires a pk value from urls. This is done automatically when using a router.
The router will create a number of urls:
Example:
router.register(r'', Client_view)
URL pattern: ^$ Name: 'client_view-list'
URL pattern: ^{pk}/$ Name: 'client_view-detail'
One of the attributes of a ViewSet is lookup_field, the lookup field allows you to change the name of the url capture you are using. In your case, you seem to have lookup_fields and specified multiple values. Try changing this to lookup_field='pk.
As a side note, it can be helpful to take a look at the restframework source code around Views.
just add lookup_field = 'pk' on the Client_view...
ie:
class Client_view(viewsets.ModelViewSet, generics.RetrieveUpdateDestroyAPIView):
queryset = Client.objects.all().order_by('-Name')
serializer_class = ClassSerializer*
lookup_field = 'pk'
I have 2 custom validation functions created using packages from PyPI, I want to inlcude them in my serializers.py in my django project before converting it to JSON using rest. Problem is i dont know where or how to put the functions in such that the code will run through it. Here is my code:
enter image description here(this is how im adding users right now, using the model's fields ive registered)
Here is my code:
/* serializers.py */
import re
import phonenumbers
from rest_framework import serializers
from phonenumbers import carrier
from validate_email import validate_email
class basicSerializer(serializers.Serializer):
emailplus = serializers.EmailField()
country = serializers.CharField(max_length=2)
phone_number = serializers.CharField(max_length=100)
def validate_emailplus(self):
email = self.validated_data.get("email")
if not validate_email(email, check_mx=True, verify=True):
raise serializers.ValidationError("Invalid email")
return email
/* views.py */
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import basic
from .serializers import basicSerializer
class basicList(APIView):
def get(self, request):
basic1 = basic.objects.all()
serializer = basicSerializer(basic1, many=True)
return Response(serializer.data)
def post(self):
pass
As you can see I am not using models.py anymore and serializers.py as some sort of model with the given email and phone fields. In order for my function to work (which is not at the moment), it needs to use get() method from the entered data and do validate_email to know if the email exists. Please tell me what changes should be made, i do not know if the problem is with views.py which still uses models.py or if i should register the serializer as a model?
To run your validations, you must call serializer.is_valid(), however, that requires data to be passed to the serializer not instances. The logic behind this is that drf validates data coming in not data already stored in your DB
Correct logic
Considerations
It looks like you are implementing a list view, but you are validating the email address, which is probably not what you intended to do in the first place. I am guess you want to validate email on create.
You can make use of drf's generic views and mixins such as GenericViewSet, ListModelMixin, and ListModelMixin
I think you have a type in validate_emailplus where you try to get the field email while the serializer declares it as emailplus
You seem not to be following PEP-8 (style guide for Python)
serializers.py
import re
import phonenumbers
from rest_framework import serializers
from phonenumbers import carrier
from validate_email import validate_email
class BasicSerializer(serializers.Serializer):
emailplus = serializers.EmailField()
country = serializers.CharField(max_length=2)
phone_number = serializers.CharField(max_length=100)
def validate_emailplus(self):
email = self.validated_data.get("emailplus")
if not validate_email(email, check_mx=True, verify=True):
raise serializers.ValidationError("Invalid email")
return email
views.py
from rest_framework import mixins, viewsets
class BasicViewSet(
viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.CreateModelMixin,
):
queryset = Basic.objects.all()
serializer_class = BasicSerializer
For a better understanding of how viewset and mixins work, I recommend checking their implementation
Validation in Admin site
From the screenshot you added, it looks like you are trying to validate in the admin site, for that consider the below code:
models.py
class Basic(models.Model):
...
def clean(self):
if not validate_email(self.email, check_mx=True, verify=True):
raise ValidationError("Invalid email")
This works because Django admin generates forms based on your models and then the forms call full_clean() on the model, which calls clean()
I got an error,
AttributeError at /app/api/get
Got AttributeError when attempting to get a value for field task_name on serializer TaskSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Color instance.
Original exception text was: 'Color' object has no attribute 'task_name'.
Now I wanna make a page that shows model's content in json format.
models.py is
from django.db import models
# Create your models here.
class Color(models.Model):
name = models.CharField(max_length=255)
background_color = models.CharField(max_length=255)
h1_color = models.CharField(max_length=255)
p_color = models.CharField(max_length=255)
def __str__(self):
return self.name
serializers.py is
from .models import Color
from rest_framework import serializers
class TaskSerializer(serializers.Serializer):
task_name = serializers.CharField(max_length=100)
status = serializers.SerializerMethodField('get_task_status')
def get_task_status(self, instance):
return instance.status.status
class Meta:
model = Color
fields = ('name',
'background_color',
'h1_color',
'p_color',
'task_name')
urls.py is
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'api/get',views.TaskGet.as_view(),name='task-get')
]
views.py is
from django.shortcuts import render
from .models import Color
from .forms import ColorForm
from .serializers import TaskSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
# Create your views here.
def index(request):
d = {
'colors': Color.objects.all(),
'form': ColorForm(),
}
return render(request, 'index.html', d)
class TaskGet(APIView):
def get(self, request, format=None):
obj = Color.objects.all()
serializers = TaskSerializer(obj, many=True)
return Response(serializers.data, status.HTTP_200_OK)
I wrote url(r'api/get',views.TaskGet.as_view(),name='task-get') in urls.py,so I really cannot understand why this error happens.I already run commands of migration of model. How can I fix this?
My ideal web page is like
You try get status by foreign key instance.status.status but in your model class Color i don't see any foreign keys or methods for it.
And for task_name did you want to see the model field name try to add source params
task_name = serializers.CharField(max_length=100, source='name')
# ^^^^^^^^^
are you sure you want serialize Task for model Color?
new edit
in your get_task_status the 'instanceis instance of serializer model, so if your modelColorhas no property or methodstatus` you will catch an error