I am trying to implement Rest api using Django framework. But when I click on the url on the default index page it gives me an assertion error at/languages/ Class LanguageSerializer missing meta.model attribute
I made all the migrations after changes in models.py but it did nothing
urls.py
from django.urls import path, include
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register('languages', views.LanguageView)
urlpatterns = [
path('', include(router.urls))
]
models.py
from django.db import models
class Language(models.Model):
name = models.CharField(max_length=50)
paradigm = models.CharField(max_length=50)
serializers.py
from rest_framework import serializers
from .models import Language
class LanguageSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'name', 'paradigm')
views.py
from django.shortcuts import render
from rest_framework import viewsets
from .models import Language
from .serializers import LanguageSerializer
class LanguageView(viewsets.ModelViewSet):
queryset = Language.objects.all()
serializer_class = LanguageSerializer
I have no clue where am I going wrong
You need to specify what model you want to serialize in the Meta class of your serializer, like:
from rest_framework import serializers
from .models import Language
class LanguageSerializer(serializers.ModelSerializer):
class Meta:
model = Language # specify the model
fields = ('id', 'name', 'paradigm')
otherwise the serializer can not determine the fields of that model, and how it will serialize the data from these fields.
Related
I am creating one crud operation in django restframework and I have created project name "portfolio" and app "stock" and store in postgres database Here is my code.
stock.models.py
from django.db import models
class Stocks(models.Model):
Name = models.CharField(max_length=50)
Number_of_Share = models.IntegerField()
Unit_Price = models.IntegerField()
ShareValue=models.IntegerField()
Total_Share_Value= models.IntegerField()
stock.serializers.py
from rest_framework import serializers
from .models import Stocks
class StocksSerializer(serializers.ModelSerializer):
class Meta:
model =Stocks
fields = '__all__'
stock.viewset.py
from rest_framework import viewsets
from .models import Stocks
from . import serializers
class StockViewset(viewsets.ModelViewSet):
queryset = Stocks.objects.all()
serializer_class = serializers.StocksSerializer
portfolio.router.py
from stock.viewsets import StockViewset
from rest_framework import routers
router = routers.DefaultRouter()
router.register('Stocks',StockViewset)
portfolio.urls.py
from django.urls import path, include
from .router import router
urlpatterns = [
# path('admin/', admin.site.urls),
path('portfolio/',include(router.urls))
]
But I am facing this error.
Exception Type: ProgrammingError
Exception Value:
relation "stock_stocks" does not exist
LINE 1: ...reValue", "stock_stocks"."Total_Share_Value" FROM "stock_sto...
Please help me solve this error.
I was just getting started on using Django's rest framework. The problem I faced is that Rest Framework didn't fetch from the right URL: I want it to get the list of Todos but it returned the URL where the API was located.
(Might be easy for many of you, but I am completely fresh to drf)
serializers
from .models import Todo
from rest_framework import serializers
class TodoSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Todo
fields = ['title', 'desc', 'level', 'created']
urls
from django.urls import path, include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'todos', views.TodoViewSet)
urlpatterns = [
path('', views.IndexView.as_view(), name='todo_all'),
path('api/', include(router.urls)),
]
views
from django.views.generic.base import TemplateView
from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer
class IndexView(TemplateView):
template_name = "todo/index.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['todos'] = Todo.objects.all()
return context
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
What I want Rest to get:
What Rest actually displayed:
Like, I want the data of the todos, not the URL. Thanks in advance.
You have used HyperlinkedModelSerializer. Try to use ModelSerializer instead.
from .models import Todo
from rest_framework import serializers
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ['title', 'desc', 'level', 'created']
I've tried to use custom user model instead of default user.
My Django project structure is below.
Project name : project_rest
App name : app_rest
To make it happen, I refer https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model
[settings.py]
AUTH_USER_MODEL = 'app_rest.User'
[models.py]
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.conf import settings
from django.contrib.auth.models import AbstractUser
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class User(AbstractUser):
username = models.CharField(unique=True, null=False, max_length=254)
password = models.CharField(max_length=200)
[serializers.py]
from app_rest.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'password')
[views.py]
from django.shortcuts import render
from app_rest.serializers import UserSerializer
from app_rest.models import User
from rest_framework import viewsets
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
[urls.py]
from django.conf.urls import url, include
from app_rest import views
from rest_framework import routers
from django.contrib import admin
from rest_framework.authtoken import views as rest_views
router = routers.DefaultRouter()
router.register(r'user', views.UserViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^token-auth/', rest_views.obtain_auth_token),
url(r'^admin/', admin.site.urls),
]
I seems work properly, But when I delete user, It throws error.
IntegrityError at /admin/app_rest/user/1/delete/ (1452, 'Cannot add or
update a child row: a foreign key constraint fails
('rest'.'django_admin_log', CONSTRAINT
'django_admin_log_user_id_c564eba6_fk_auth_user_id' FOREIGN KEY
('user_id') REFERENCES 'auth_user' ('id'))')
How can I solve this issue?
The error is pretty self explanatory. The record you are trying to delete is related to another one by a foreign key and it cannot be deleted as it would break referential integrity.
You need to alter that id with something like ON DELETE CASCADE or its equivalent, or allow the user to be null on the related table (if that's possible).
I have an app developed using Django and Django Rest framework. I would like to add the django-reversion feature to my app.
I have already tried http://django-reversion.readthedocs.org/en/latest/api.html#low-level-api but I have failed to make specific changes to my app.
Below are the modules of the app where I would like to include the Django-reversion to restore objects if they get deleted. How to set the django-reversion configuration for the below modules
admin.py:-
from django.contrib import admin
from.models import Category
admin.site.register(Category)
models.py:-
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=64, unique=True)
def __unicode__(self):
return self.name
serializers.py:-
from rest_framework import serializers
from .models import Category
class CategorySerializer(serializers.ModelSerializer):
courses = serializers.HyperlinkedRelatedField(
many=True
read_only=True
view_name='course-detail'
)
class Meta:
model = Category
fields = ('pk', 'name', 'courses',)
urls.py :-
from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from .import views
from django.conf.urls import include
category_list = views.CategoryViewSet.as_view({
'get': 'list',
'post': 'create'
})
category_detail = views.CategoryViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy',
})
urlpatterns = format_suffix_patterns([
url(r'^categories/$',
category_list,
name='category-list'),
url(r'^categories/(?P<pk>[0-9]+)/$',
category_detail,
name='category-detail'),
])
urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
]
views.py :-
from rest_framework import permissions
from rest_framework import viewsets
from .models import Category
from .serializers import CategorySerializer
class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
permission_classes = (permissions.IsAuthenticatedorReadOnly,)
The simplest way to create revisions is to use reversion.middleware.RevisionMiddleware. This will automatically wrap every request in a revision, ensuring that all changes to your models will be added to their version history.
To enable the revision middleware, simply add it to your MIDDLEWARE_CLASSES setting as follows:
MIDDLEWARE_CLASSES = (
'reversion.middleware.RevisionMiddleware',
# Other middleware goes here...
)
Any thing more complex with this will require adding API calls through your code in away that wraps specific save calls in ways that you decide.
admin.py
from django.contrib import admin
from.models import Category
import reversion
class BaseReversionAdmin(reversion.VersionAdmin):
pass
admin.site.register(Category, BaseReversionAdmin)
also added reversion to installed_apps and middlewareclasses.
Finally i could see the "recover deleted objects button".
I discovered that since rest_framework.viewsets.ModelViewSet inherits from django.views.generic.View so you can also use the reversion.views.RevisionMixin to create revisions instead of having to use the middleware if you want.
From the question above this would look like the following:
from rest_framework import permissions
from rest_framework import viewsets
from .models import Category
from .serializers import CategorySerializer
from reversion.views import RevisionMixin
class CategoryViewSet(RevisionMixin, viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
permission_classes = (permissions.IsAuthenticatedorReadOnly,)
You can read more about the specifics of how you can use RevisionMixin here: https://django-reversion.readthedocs.io/en/stable/views.html#reversion-views-revisionmixin
I'm trying to use autocomplete_light and taggit both on an admin form.
I've read the docs on integrating autocomplete light and taggit here,
and the docs on integrating autocomplete light in the admin here. But there seems to be little (or no) discussion on doing both at the same time.
what I've got so far.
In models.py:
from django.db import models
from taggit.managers import TaggableManager
from taggit.models import TagBase, GenericTaggedItemBase
class MyTag(TagBase):
description = models.CharField(max_length = 250, blank = True, null = True)
class MyTagThroughModel(GenericTaggedItemBase):
tag = models.ForeignKey(MyTag, related_name = "tagged_items")
class MyModel(models.Model):
Name = models.CharField(max_length = 200)
...
tags = TaggableManager(through = MyTagThroughModel)
In autocomplete_light_registry.py:
import autocomplete_light
from models import MyTag
autocomplete_light.register(MyTag)
How am I meant to structure admin.py?
If this was a non-admin form, the field would be given as:
tags = TagField(widget = TagWidget('MyTagAutocomplete'))
If this was a non-taggit admin form, I would add the following to the admin model class:
form = autocomplete_light.modelform_factory(MyTag)
How can I combine the two?
How am I meant to structure admin.py?
Here's an example to autocomplete Tags. It shows you how autocomplete_light and taggit work on admin and non-admin forms.
models.py
from django.db import models
from taggit.managers import TaggableManager
class MyModel(models.Model):
name = models.CharField(max_length = 200)
tags = TaggableManager(blank=True)
autocomplete_light_registry.py
import autocomplete_light
from taggit.models import Tag
autocomplete_light.register(Tag)
forms.py
from django import forms
import autocomplete_light
from autocomplete_light.contrib import taggit_tagfield
from models import MyModel
class MyModelForm(forms.ModelForm):
tags = taggit_tagfield.TagField(widget=taggit_tagfield.TagWidget('TagAutocomplete'))
class Meta:
model = MyModel
widgets = {
'tags': autocomplete_light.TextWidget('TagAutocomplete'),
}
admin.py
from django.contrib import admin
import autocomplete_light
from models import MyModel
from forms import MyModelForm
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
model = MyModel
admin.site.register(MyModel, MyModelAdmin)
views.py
from django.views.generic.edit import CreateView
from models import MyModel
from forms import MyModelForm
class CreateMyModel(CreateView):
model = MyModel
form_class = MyModelForm
urls.py
from django.conf.urls import patterns, url
from views import CreateMyModel
urlpatterns = patterns('',
url(r'^create/$', CreateMyModel.as_view()),
)
The quick docs seem to be more straightforward to understand than the docs you were looking at.
Consider using django-taggit-autosuggest instead.
It works best with the django-grapelli admin skin.