Well, I tried to start GraphQL on Django's local server. But got a mistake that:
You need to pass a valid Django Model in UserType.Meta, received "auth.User".
Exception value is:
Exception Value:
You need to pass a valid Django Model in UserType.Meta, received "auth.User".
To be honest, I don't really understand where I can find 'UserType.Meta. The model about users looks like (models.py):
# user - связь с пользователем один-к-одному
# website - юрл, по которому можно больше узнать о пользователе
# bio - о себе (Капитан Очевидность)
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
)
website = models.URLField(blank=True)
bio = models.CharField(max_length=240, blank=True)
# __str__ - более удобное отобажение в админке
def __str__(self):
return self.user.name
'schema.py' looks like:
from django.conf import settings
from graphene_django import DjangoObjectType
from Start import models
import graphene
# Всё заканчивается на type ибо они соответсвуют Graphql
class UserType(DjangoObjectType):
class Meta:
model = settings.AUTH_USER_MODEL
class AuthorType(DjangoObjectType):
class Meta:
model = models.Profile
class FileType(DjangoObjectType):
class Meta:
model = models.File
class TagType(DjangoObjectType):
class Meta:
model = models.Tag
So, what can I do to solve this problem?
That's because settings.AUTH_USER_MODEL returns the string "auth.User" instead of the model User. The following should fix your issue:
from django.contrib.auth import get_user_model
User = get_user_model()
class UserType(DjangoObjectType):
class Meta:
model = User
You can also import User directly from django.contrib.auth.models but get_user_model() is preferred as it works also when you use a custom auth model in your settings file.
Related
Hello I had to rewrite my user model for add some filed, I used AbstractUser
My models:
It's on blog app:
class Article(models.Model):
author = models.ForeignKey(User , null=True, on_delete=models.SET_NULL , related_name='articles' , verbose_name='نویسنده')...
it's on account app:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_authour = models.BooleanField(default=False, verbose_name="وضعیت نویسندگی")
special_user = models.DateTimeField(default=timezone.now, verbose_name="کاربر ویژه تا")
def is_special_user(self):
if self.special_user > timezone.now():
return True
else:
return False
is_special_user.boolean = True
is_special_user.short_description = "وضغیت کاربر ویژه"
I imported my User view in this way:
from account.models import User
And I added this to my setting:
AUTH_USER_MODEL = 'account.User'
when I migrate I get this error:
blog.Article.author: (fields.E301) Field defines a relation with the
model 'auth.User', which has been swapped out.
HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
I searched my error but I can't find my solution
The current User passed to the ForeignKey points to the auth.User right now, not your custom User.
As the HINT itself suggests, use settings.AUTH_USER_MODEL instead of User in your author field in Article model.
class Article(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL, related_name='articles', verbose_name='نویسنده')...
Link to django docs: Using a custom user model
Did you register the model in the app's admin.py?
Furthermore, changing the user model mid-project...this can be a hassle, look here: Changing to a custom user model mid-project
I think you are importing User model from django auth app.
Change the author field in the Article model as follows:
class Article(models.Model):
author = models.ForeignKey('account.User', null=True, on_delete=models.SET_NULL, related_name='articles', verbose_name='نویسنده')
...
I couldn't find a solution to my problem and would appreciate comments/help on this.
I would like to develop a multiple user type model in Django, along the lines of this video where the author is using Django Proxy Models.
Situation
I have a list of XX projects (proj01, proj02 , projXX, ...).
All these projects have their specific page that can be accessed through a specific url mysite/projXX/
I have multiple users: Adam, Bob, Caroline, Dany, Ed, ...
Each user can have several roles according to the project they are working on (e.g. manager, developer, documentarist, reviewer, editor, ...)
A user can have a different role according to the project. E.g. Adam can be reviewer on proj01 but editor on proj02 while Bob can be editor on proj01 but reviewer on proj02, etc..
I started defining multiple user types in the models.py file below (only reviewer and editor roles):
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
class Types(models.TextChoices):
EDITOR= "EDITOR", "Editor"
REVIEWER = "REVIEWER", "Reviewer"
base_type = Types.EDITOR
type = models.CharField(
_("Type"), max_length=50, choices=Types.choices, default=base_type
)
name = models.CharField(_("Name of User"), blank=True, max_length=255)
def get_absolute_url(self):
return reverse("users:detail", kwargs={"username": self.username})
def save(self, *args, **kwargs):
if not self.id:
self.type = self.base_type
return super().save(*args, **kwargs)
class EditorManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.EDITOR)
class ReviewerManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.REVIEWER)
class EditorMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
gadgets = models.TextField()
class Editor(User):
base_type = User.Types.EDITOR
objects = EditorManager()
class Meta:
proxy = True
def edit(self):
return "Edition in progress"
class ReviewerMore(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
model = models.CharField(max_length=255)
make = models.CharField(max_length=255)
year = models.IntegerField()
class Reviewer(User):
base_type = User.Types.REVIEWER
objects = ReviewerManager()
#property
def more(self):
return self.reviewermore
class Meta:
proxy = True
def review(self):
return "In Review"
Question:
What is the best way to handle the fact that the role of the user can change according to the project page he/she is visiting?
Example: If Adam is logged in and visits the page mysite/proj01/ I would like him to access only the content allowed for a reviewer while if Adam visit mysite/proj02/, I would like the user to see only the content allowed to the editor.
Ideally, I would like each user to have its unique entry in the user database. I was thinking that the project-dependent role level could be stored as a dictionary? For example:
{'proj01':'reviewer', 'proj02':'editor', 'projxx': 'roleY', ... }
How would combine this user model and the list of project-dependent permissions?
Edit 02/07/21
Add example files for a project app, models.py and views.py :
# projects/models.py
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
class Project(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("project_detail", args=[str(self.id)])
# projects/views.py
from django.contrib.auth.mixins import (
LoginRequiredMixin,
UserPassesTestMixin,
)
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Project
class ProjectListView(LoginRequiredMixin, ListView):
model = Project
template_name = "project_list.html"
class ProjectDetailView(LoginRequiredMixin, DetailView):
model = Article
template_name = "project_detail.html"
class ProjectUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
fields = (
"title",
"body",
)
template_name = "project_edit.html"
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
If you have projects as a model. You can add custom permissions to the model. Then assign those permissions to your users appropriately for each project (actually easily add/remove permissions too).
Then use either user_passes_test or permissions_required in your views/template to restrict what users can see/access/edit.
class Project(models.Model):
project_name = ...
class RoleType(models.Model):
role_name = models.CharField
# Permission boolean flags
can_edit = models.Boolean
can_view = models.Boolean
class ProjectRole(models.Model):
project = models.ForeignKey('Project', ...)
role = models.ForeignKey('RoleType', ...)
user = models.ForeignKey('User', ...)
Now you can reverse lookup based on project or user
# To show all assigned users and their roles for a project
foo_project = Project.objects.get(project_name='foo')
project_roles = ProjectRole.objects.filter(project=foo_project)
You can also restrict your views and templates by roles and their permissions boolean flags.
Create groups that defines your Roles, for example : Group1: Editor, Group2:Manager and so on
Assign each user to the specified group ( you can do it in python manage.py shell or in admin panel )
Add restrictions on the view, for example: /mysite/projx/ view is restricted to groupA, you can check the following question that helps you with this point: https://stackoverflow.com/a/4789038/13508969
For example:
GroupA : GlobalEditor ( Bob can edit in projx and projy , and can only view projz )
GroupB : viewonly ( Adam can only view the content of the projs )
and so on
forms.py
from django import forms
from django.contrib.auth.models import User
from basic_app.models import UserProfileInfo
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
models = User
feilds = ['username','email','password']
class UserProfileInfoForm(forms.ModelForm):
class Meta:
models = UserProfileInfo
feilds = ('portfolio_site','profile_pic')
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
portfolio_site = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
def __str__(self):
return self.user.username
Error screenshot
As you can see in the above error image, my code is not functioning properly. I have added my forms.py and models.py code. Please help me resolve the issue.
It should be model instead of models inside the Meta class of UserForm.
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User # model instead of models here
feilds = ['username','email','password']
when i am migrating the code below i get the following error ----ERRORS:
users.UserStripe.user: (fields.E300) Field defines a relation with model 'settings.AUTH_USER_MODEL', which is either not installed, or is abstract.
users.UserStripe.user: (fields.E307) The field users.UserStripe.user was declared with a lazy reference to 'settings.auth_user_model', but app 'settings' isn't installed.---
I understand that it relates to the fact i have 'user' in the stripe and profile class but I'm not sure how to stop the error. any guidance would be appreciated!
models.py - users
import stripe
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
stripe.api_key = '****************'
class UserStripe(models.Model):
**user = models.OneToOneField('settings.AUTH_USER_MODEL', on_delete=models.CASCADE)**
stripe_id = models.CharField(max_length=120)
def __str__(self):
return str(self.stripe_id)
class Profile(models.Model):
**user = models.OneToOneField(User, on_delete=models.CASCADE)**
image = models.ImageField(default='', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
You should not use 'settings.AUTH_USER_MODEL' as a string literal, since then Django will look for a model named AUTH_USER_MODEL in the settings app. But there is no settings app, and nor is there a model with that name.
You should pass the value of settings.AUTH_USER_MODEL:
from django.db import models
from django.conf import settings
class UserStripe(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
stripe_id = models.CharField(max_length=120)
def __str__(self):
return str(self.stripe_id)
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
image = models.ImageField(default='', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Project Name : fusion
App Name : admin_lte
Python 3.7
Django 2
MySql
Question is "I want to register sub model in django admin-panel",when i write code for model registration in admin.py file that time occurred below error.
django.core.exceptions.ImproperlyConfigured: The model Device is abstract, so it cannot be registered with admin.
NOTE : I used multiple separated model file.
device.py (Model File)
from django.db import models
class Device(models.Model):
device_type = models.CharField(max_length=100,blank=False)
price = models.IntegerField()
status = models.CharField(max_length=10, default="SOLD")
issues = models.CharField(max_length=100, default="No Issues")
class Meta:
abstract = True
def __str__(self):
return 'Device_type:{0} Price:{1}'.format(self.device_type,self.price)
#Inheritance Concept
class Laptop(Device):
pass
class Meta:
db_table = "laptop"
class Desktop(Device):
pass
class Meta:
db_table = "Desktop"
class Mobile(Device):
pass
class Meta:
db_table = "Mobile"
__init__.py File
from django_adminlte.models.employee import Employee
from django_adminlte.models.device import Device
admin.py
from django.contrib import admin
from.models import Employee
from.models import Device
admin.site.register (Employee)
admin.site.register (Device)
I want to show sub model (Desktop,Laptop,Mobile) in admin panel so admin can add some data from admin panel.
Project Structure Image :
I can see in your code Device is a abstract model. So, we should not register it because abstract models do not have associated tables in databases.
from django.contrib import admin
from .models import Employee, Laptop, Mobile, Desktop
admin.site.register(Employee)
admin.site.register(Laptop)
admin.site.register(Mobile)
admin.site.register(Desktop)
I also got a problem when trying to generate an admin CRUD for a class inheriting from an abstract class. But the cause was different so I'll leave my case here in case it helps someone else.
In my case, the problem was that I forgot to make the abstract class inherit from django's models.Model.
Example Code:
time.py
from django.db import models
from applications.utils import UniqueNameMixin
class Month(UniqueNameMixin):
starting_date = models.DateField()
ending_date = models.DateField()
class TimeSensible(models.Model): # Here '(models.Model)' was missing.
class Meta:
abstract = True
month = models.ForeignKey(Month, models.PROTECT)
transaction.py
from django.db import models
from applications.core.models.cash_flow import Concept
from applications.core.models.financial_position import Account
from applications.core.models.time import TimeSensible
class Transaction(models.Model, TimeSensible):
concept = models.ForeignKey(Concept, models.PROTECT, blank=True, null=True)
amount = models.DecimalField(max_digits=10, decimal_places=2)
account = models.ForeignKey(Account, models.PROTECT)
detail = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return '{} - {} - {} - {}'.format(self.month, self.concept, self.amount, self.account)
The error I got:
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: The model Transaction is abstract, so it cannot be registered with admin.