Can't import ObtainAuthToken - django

I am new to Django.
In the course that i'm using he is importing ObtainAuthToken like this:
from rest_framework.authtoken.views import ObtainAuthToken
But when i try to do the same thing i get this exception:
Abstract base class containing model fields not permitted for proxy model 'TokenProxy'.
What am i doing wrong?
I have added both my app and 'rest_framework' to my Installed_Apps.
If this needs clarification i can send my views and urls files also.
Thanks :)

This seems to be a bug in Django REST Framework 3.12.x. https://github.com/encode/django-rest-framework/issues/7561
For the time being, downgrade to 3.11.x (pip install -U 'djangorestframework<3.12').

Related

Django / app import problem from submodule

I'm writing my own Django app, and trying to import submodule from my core library like that:
INSTALLED_APPS = [
'django.contrib.admin',
...
'core.login',
]
And interpreter gives me:
django.core.exceptions.ImproperlyConfigured:
Cannot import 'login'.
Check that 'core.login.apps.CustomloginConfig.name' is correct.
So login.apps looks like that
from django.apps import AppConfig
class CustomloginConfig(AppConfig):
name = 'login'
Are there any rules how I can edit this files to start Django properly?
apps.py file needs to be as so
from django.apps import AppConfig
class CustomloginConfig(AppConfig):
name = 'core.login'
This is where you tell django that I have registered this app 'core.login' and where to find it.
If login folder is in a core folder, then the above should work.
I think theres a lot of django apps out there that have organized things this way.
One being Kiwi but Im sure theres many others.

Django REST framework backend filtering issues with React.js frontend

So I'm trying to put together a not-so-simple Todo application, using some perhaps superfluous practices and technologies to showcase development skills. The application is meant to be a sort of Trello replica. The backend is Django utilizing the django REST framework for RESTful api requests from the frontend which is React.js. In short, I'm having trouble with my django_backend, and maybe specifically django-rest-framework, which doesn't seem to appreciate being asked to filter its querysets. I've tried several django packages as well as the method described in the DRF documentation, which I will elaborate, but my attempts aren't working and I would appreciate some guidance. Thank you!
Backend Setup
I've just completed implementing redux-saga and I have a few very basic sagas that get EVERY instance of each of the models. But I obviously don't want to request every instance, so we should filter the response.
Django REST framework uses built in classes like Serializers and ViewSets to return lists of model instances that the rest-framework can respond to a request with. These were my initial viewsets for testing requests to the backend, and they all returned the appropriate JSON object to my frontend:
viewsets.py
from rest_framework import viewsets
from corkboard.models import Card, Stage, Board
from .serializers import CardSerializer, StageSerializer, BoardSerializer
# Card is the model for a "Todo" Instance
# Todo Cards viewset
class CardViewSet(viewsets.ModelViewSet):
queryset = Card.objects.all()
serializer_class = CardSerializer
# Stages of completion model viewsets
class StageViewSet(viewsets.ModelViewSet):
queryset = Stage.objects.all()
serializer_class = StageSerializer
# Board that "houses" all stages and cards
class BoardViewSet(viewsets.ModelViewSet):
queryset = Board.objects.all()
serializer_class = BoardSerializer
viewseturls.py:
from rest_framework import routers
from .views import CardViewSet, StageViewSet, BoardViewSet
# registering router paths for each of the viewsets
router = routers.DefaultRouter()
router.register('cards', CardViewSet, 'cards')
router.register('stages', StageViewSet, 'stages')
router.register('boards', BoardViewSet, 'boards')
urlpatterns = router.urls
and these urls are used in the calls from the frontend via axios. Initially I tried simply changing the url in the request from something like
axios.get(`http://localhost:8000/api/cards)
to
axios.get(`http://localhost:800/api/cards/?stage=1`)
This different url responded with the same JSON object (ALL Card instances, regardless of stage)
Looking into the DRF filtering docs revealed some filtering methods that seem helpful. They involve creating another view class to override the get_queryset method as such:
from rest-framework import generics
class CardsFilteredByStageViewSet(generics.ListAPIView):
serializer_class = TodoSerializer
def get_queryset(self):
"""
This view should return a list of all the todo cards for
the stage as determined by the stage portion of the URL.
"""
stage = self.kwargs['stage']
return Card.objects.filter(stage=stage)
Note that this involves using the
rest-framework.generics.ListAPIView
and that I also tried inheriting from
views.ViewSets
After both, I go edit the router url in urls.py:
from .views import StageCardViewSet
router.register('stage_cards', StageCardViewSet, 'stage_cards')
and then try
http://localhost:8000/api/stage_cards/
and
http://localhost:8000/api/stage_cards/?stage=1
but got a KeyError for both:
Request Method: GET
Request URL: http://localhost:8000/api/stage_cards/?stage=1
Django Version: 3.0.5
Exception Type: KeyError
Exception Value: 'stage'
The DRF docs also provide sources for packages like django-filter, and installation seems to go fine. I used
pipenv install django-filter
As you can see later on in this post, this package appears in my requirements.txt as well as my Pipfile, so it is certainly installed. It's also been added to django_backend.settings. Yes, the 's' is supposed to be in 'django-filters' below:
INSTALLED_APPS = [
# confusing pluralization
'django-filters',
...
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
],
...
}
This should give an error if it's not added as a package, correct?
After it's added as an installed app develop the existing viewsets (or generic lists, depending on what you're using)
from django_filters.rest_framework import DjangoFilterBackend #added
class CardViewSet(viewsets.ModelViewSet):
queryset = Card.objects.all()
serializer_class = CardSerializer
filter_backends = [DjangoFilterBackend] #added
filterset_fields = ['stage', 'id'] #added
But I get an "Unable to import" Error in the IDE. Exploring this error revealed this article which suggested addition of django-rest-framework-filters, but immediately after installation, I began getting errors about not having django.utils.six, which I found has been removed from django > 3, but is required for django-rest-framework-filters. Though some other documentation mentions a lot of d-r-r-f features being added back into the django-filter. Removing/uninstalling d-r-f-f fixes the errors and allows the server to run, but I'm still getting red underlines about being unable to import django-filter to my viewsets:
Unable to import 'django_filters.rest_framework'pylint(import-error)
in the updated views:
from django_filters.rest_framework import DjangoFilterBackend
#^^^ here is the unable to import error underline
I just want to filter the instances of my models so I can return relevant information to the frontend. Please help.
Extra, maybe relevant info
Though my project also contains a Pipfile for my local VDE, it also has a requirements.txt file used in the installation of dependencies for Docker builds. I'm including both.
requirements.txt:
appdirs==1.4.3
asgiref==3.2.7
astroid==2.3.3
certifi==2019.11.28
distlib==0.3.0
Django==3.0.5
django-environ==0.4.5
django-filter==2.2.0
djangorestframework==3.11.0
filelock==3.0.12
isort==4.3.21
lazy-object-proxy==1.4.3
mccabe==0.6.1
pipenv==2018.11.26
pylint==2.4.4
pylint-django==2.0.15
pylint-plugin-utils==0.6
pytz==2019.3
six==1.14.0
sqlparse==0.3.1
virtualenv==20.0.2
virtualenv-clone==0.5.3
wrapt==1.11.2
Pipfile:
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
appdirs = "==1.4.3"
asgiref = "==3.2.7"
astroid = "==2.3.3"
certifi = "==2019.11.28"
distlib = "==0.3.0"
djangorestframework = "==3.11.0"
filelock = "==3.0.12"
isort = "==4.3.21"
lazy-object-proxy = "==1.4.3"
mccabe = "==0.6.1"
pipenv = "==2018.11.26"
pylint = "==2.4.4"
pytz = "==2019.3"
six = "==1.14.0"
sqlparse = "==0.3.1"
virtualenv = "==20.0.2"
virtualenv-clone = "==0.5.3"
wrapt = "==1.11.2"
Django = "==3.0.5"
django-environ = "*"
django-filter = "*"
[requires]
python_version = "3.8"
The Dockerfile for django_backend:
# Use an official Python runtime as a parent image
FROM python:latest
# Adding backend directory to make absolute filepaths consistent across services
WORKDIR /usr/src/app/django-backend
# Install Python dependencies
ADD requirements.txt .
RUN pip3 install --upgrade pip -r requirements.txt
# Add the rest of the code
ADD . .
# Make port 8000 available for the app
EXPOSE 8000
# Be sure to use 0.0.0.0 for the host within the Docker container,
# otherwise the browser won't be able to find it
CMD python3 manage.py runserver 0.0.0.0:8000
Frontend
The frontend is React.js with redux and redux-saga. I don't believe it's relevant to this post as everything was working well until I started changing code in the django_backend
Of course ask any questions if I wasn't clear enough, and thanks in advance.
My first post ended up being because of a silly mistake. Answering it myself, because why not.
The pylint error is a big flag. This may just be an IDE configuration issue, and if I'm able to host locally with python manage.py runserver without any errors, then it's possible you implemented it correctly. If all I'm getting is a pylint error then try running it anyway. As you said it ran with no errors right after removing django-rest-framework-filters.
The code sections I gave seemed like the correct implementation of django-filter as the DRF docs do a decent job of explaining how to use it for basic filtering. They also recommend another package called django-rest-framework-filters as mentioned, but I understand there are issues with django.utils.six being removed from Django >3. One of that thread's comments includes a fix via installing the six package that allegedly works with Django 3.0.4, so I would explore that if instance interrelationships are important for filtering.
Indeed, I had implemented it correctly. My guess is that I missed it because of some other Error overlap along the process, and the pylint error threw me off the scent. I simply missed that it was in fact running; I just didn't test its functionality. I also wanted to start using Stackoverflow as a resource for development, but going through the process brought me to the answer. Funny.
Reiterating correct implementation procedure:
pipenv install django-filter
Add to django_backend.settings:
INSTALLED_APPS = [
# confusing pluralization
'django-filters',
...
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
],
...
}
and refactor of viewsets:
from django_filters.rest_framework import DjangoFilterBackend # added
# Todo Card viewset now filterable via filterset_fields
class CardViewSet(viewsets.ModelViewSet):
queryset = Card.objects.all()
serializer_class = CardSerializer
filter_backends = [DjangoFilterBackend] # added
filterset_fields = ['stage', 'title', 'id'] # added
Now after python manage.py runserver go to the right url (http://localhost:8000/api/cards/?stage=1) and you should see only cards in stage 1. This same url structures will hopefully also be callable from the frontend. But the django rest framework UI returns a filtered list. Success.
The pylint error was easily solved by going to the settings.json file of my IDE (which happens to be VSCode, though I'm considering alternatives) and adjusting as such:
{
"python.PythonPath": "/user/local/bin", // added
...
}
The import error disappeared.

Django unable to load model into views

I am trying to import my models into views.py but I am unable to do so. However I am able to register them on the admin site but when I use the same code I used in admin.py to import the models into views.py, I get an error. I am using djongo so I am not sure if that changes anything about how to import them and I cannot seem to find the documentation for it.
models.py
from djongo import models
class Round(models.Model):
round_num = models.IntegerField(default=0)
admin.py
from django.contrib import admin
from .models import Round
admin.site.register(Round)
views.py
from .models import Round
When I try and run my views.py file I get the following error: ModuleNotFoundError: No module named 'main.models'; 'main' is not a package
Also my views, admin, and models file are all in the same directory. I have made the migrations and I can see my Round model in MongoDB. The only thing I cannot do is import it to the view
You need to have an __init__.py file in your directory. It should be inside of your main folder and at the same level as your views.py and models.py
As a workaround, since the models properly migrate to MongoDB. Using pymongo I have just connected to Mongo and have rendered data into my views this way. It works fine so if anybody else has an issue loading in their models, you can always just connect directly to the DB.

Why I couldn’t use get_user_model() at import time

Just as the title, I cannot import usercreationform
. The exception is model haven’t been loaded. It’s only appears in Django 1.10. There’s no such problem in Django 1.11 . I know it depends on whether get_user_model() can be called at runtime. What should I do to solve it in Django 1.10?
You have to use
from django.contrib.auth import(
login,
logout,
get_user_model,
authenticate,
)
at the beginning of the file. Now I hope you can solve your problem :)

Add all models to admin site django 1.9

I need to add my model to my admin site on django 1.9,
I was using this code earlier:
for model in get_model(get_app('campaign')):
admin.site.register(model)
However, it isn't supported by django 1.9 verison. Is there a new way to do this?
You can use the get_models() method of the app config.
from django.contrib import admin
from django.apps import apps
myapp = apps.get_app_config('myapp')
for model in myapp.get_models():
admin.site.register(model)
In modern versions of Django (I'm not sure whether it will work for Django < 1.10), you can simplify this to:
myapp = apps.get_app_config('myapp')
admin.site.register(myapp.get_models())