AbstractBaseUser.get_username() missing 1 required positional argument: 'self' | Error while accessing current user's username - django-models

I am trying to access the Id of current logged in User. but i am getting the below error.
models.py of derived model
from django.db import models
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from accounts.models import CustomUser
# Create your models here.
class PostProblem(models.Model):
problem_type_choices = (
('c','Confidential'),
('sc','Semi-confidential'),
('p','Public')
)
problem_category_choices = (
('agriculture','Agriculture'),
('computer_science','Computer Science'),
('social_studies','Social Studies'),
('environment','Environmental Science'),
('mathematics','Mathematics'),
('engineering','Engineering'),
('physics','physics'),
('chemistry','chemistry'),
('other','Other')
)
author = models.ForeignKey("accounts.CustomUser", verbose_name= "Creater", default = CustomUser.get_username ,on_delete=models.CASCADE)
problem_title = models.CharField(max_length=200, verbose_name="Problem's title")
problem_type = models.CharField(choices=problem_type_choices,max_length=5, verbose_name='Confidentiality of the problem ')
problem_category = models.CharField(choices=problem_category_choices, max_length=50, verbose_name="Catrgory of the problem")
problem_brief = models.CharField(max_length=1000, verbose_name='Breif description of the problem ')
problem_description = models.TextField(verbose_name='Problem complete description ')
problem_reward = models.IntegerField(verbose_name='Prize money for providing the solution ')
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now
self.save()
def __str__(self):
return self.problem_title
def get_absolute_url(self):
return reverse("problem_detail", kwargs={"pk": self.pk})
def approve_solutions(self):
return self.solutions.filter(approved_solutions = True)
views.py
from django.shortcuts import render
from django.urls import reverse_lazy
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin
from problems.models import PostProblem, Solutions
from problems.forms import PostProblemForm, SolutionsForm
from django.views.generic import TemplateView, CreateView, DetailView, DeleteView, UpdateView, ListView
# Create your views here.
class PostProblemCreateView(CreateView, LoginRequiredMixin):
login_url = 'login/'
redirect_field_name = 'problems/problem_detail.html'
form_class = PostProblemForm
model = PostProblem
forms.py
from django import forms
from problems.models import PostProblem, Solutions
class PostProblemForm(forms.ModelForm):
class Meta:
model = PostProblem
fields = ("problem_title","problem_type","problem_category","problem_brief","problem_description","problem_reward")
widgets = {
'problem_title':forms.TextInput(attrs={'class':'textinputclass'}),
'problem_type': forms.TextInput(attrs={'class':'choice_input'}),
'problem_category':forms.TextInput(attrs={'class':'choice_input'}),
'problem_brief': forms.Textarea(attrs={'class':'editable medium-editor-textarea post_brief'}),
'problem_description': forms.Textarea(attrs={'class':'editable medium-editor-textarea post_complete'}),
'problem_reward': forms.TextInput(attrs={'class':'textinputclass'})
}
model.py of base model
from django.db import models
from django.contrib import auth
from django.urls import reverse
# Create your models here.
# for custom user
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, User
from .managers import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
'''Model representation for user'''
user_type_choices = (
('ps','Problem Solver'),
('pp','Problem Provider')
)
account_type_choices = (
('o','Organization'),
('i','Individual')
)
user_type = models.CharField(max_length=5, choices=user_type_choices, default='pp', verbose_name="Who you are? ")
account_type = models.CharField(max_length=5, choices= account_type_choices, default='o', verbose_name="Account Type ")
email = models.EmailField(max_length=50, unique=True, blank=False, verbose_name="Your Email ")
is_active = models.BooleanField(default=True) # anyone who signs up for thsi application is by default an active user
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False) # the person who has highest level of control over database
# need to specify manager class for this user
objects = CustomUserManager()
# we are not placing password field here because the password field will always be required
REQUIRED_FIELDS = ['user_type', 'account_type']
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
I searched the web for answers but they have mentioned only about accessing current user id in function based views. How can I resolve this kind of error? I am new to Django.

Related

I am getting null value in column "user_id" violates not-null constraint, how can I get foreign key data to register on my comment form?

This my models.py file
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class UserAccountManager(BaseUserManager):
def create_user(self, name, email, password, **other_fields):
if not email:
raise ValueError('Users must have an email adress')
email = self.normalize_email(email)
user = self.model(name=name, email=email, password=password)
user.set_password(password)
user.save()
return user
def create_superuser(self, name, email, password = None, **other_fields):
other_fields.setdefault('is_staff', True)
other_fields.setdefault('is_superuser', True)
other_fields.setdefault('is_active', True)
return self.create_user(name=name, email=email, password = password, is_superuser=True)
class UserAccount(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=355, unique=False)
is_superuser = models.BooleanField(default=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=True)
objects = UserAccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def __str__(self):
return str(self.id)
I have a foreign key on my comment model, I tested this on django admin and it works fine, but with my comment form, the foreign key isn't populating, i just get "null value in column "user_id" violates not-null constraint", I dont know what im doing wrong
class Comment(models.Model):
comment = models.CharField(max_length=250)
user = models.ForeignKey(UserAccount, on_delete=models.CASCADE)
def __str__(self):
return str(self.user.id)
serializers.py
from djoser.serializers import UserCreateSerializer
from django.contrib.auth import get_user_model
from rest_framework.serializers import ModelSerializer
from accounts.models import Comment
User = get_user_model()
class UserCreateSerializer(UserCreateSerializer):
class Meta(UserCreateSerializer.Meta):
model = User
fields = ('id', 'name', 'email', 'password')
I am reffering my foreign key user as a field, i'm not sure if that is correct.
class CommentSerializer(ModelSerializer):
class Meta:
model = Comment
fields=('id', 'comment', 'user')
viewsets.py
from rest_framework import viewsets
from . import models
from . import serializers
class CommentViewset(viewsets.ModelViewSet):
queryset = models.Comment.objects.all()
serializer_class = serializers.CommentSerializer
router.py
from accounts.viewsets import CommentViewset
from rest_framework import routers
router = routers.DefaultRouter()
router.register('comment', CommentViewset)
You need to add user_id field for writing in the serializer.
class CommentSerializer(ModelSerializer):
class Meta:
model = Comment
fields=('id', 'comment', 'user')
extra_kwargs = {
'user': { 'read_only': True }
}
def create(self, validated_data):
new_comment = Comment(**validated_data)
new_comment.user_id = self.context['request'].user.id
new_comment.save()
return new_comment

Identify the custom user model in REST_FRAMEWORK settings Django

I'm new in Django rest_framework. I'm using a custom user model and djoser as my authentication system. I want to use my custom user model in the djoser register view and I don't know how to identify that in the rest_framework settings?
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSIONS_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
}
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, phone, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have an username")
if not phone:
raise ValueError("Users must have a phone number")
user = self.model(
email=self.normalize_email(email),
username=username,
phone=phone
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email, username, phone, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
phone=phone,
password=password
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email",max_length=60, unique=True)
username = models.CharField(max_length=60,unique=True)
phone = models.CharField(max_length=60,unique=True)
date_joined = models.DateTimeField(verbose_name="date joined",auto_now_add=True)
last_login = models.DateTimeField(verbose_name="last login",auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
first_name = models.CharField(max_length=60,null=True)
last_name = models.CharField(max_length=60,null=True)
wilaya = models.CharField(max_length=60,null=True)
city = models.CharField(max_length=60,null=True)
address = models.CharField(max_length=200,null=True)
store_coordinates = models.CharField(max_length=60,null=True)
documents1 = models.CharField(max_length=60,null=True)
documents2 = models.CharField(max_length=60,null=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email','phone']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
What should I add to use my custom user model in djoser register view?
You're doing almost everything right, but you need to tell Django in the settings what user model it should use.
In models.py use something like this
from django.contrib.auth.models import AbstractUser
from .managers import UserManager
class User(AbstractUser):
# Add whatever fields you want
# Use your custom manager
objects = UserManager()
In settings.py
# Tell Django what user model should be used
AUTH_USER_MODEL = 'auth.User' # app_label.model
make sure you use python manage.py makemigrations && python manage.py migrate to create your custom user model.
Enjoy!

Admin doesn't register address type how come (I use django)?

This is the problem:
if a address is submitted the address should automatically register a ADDRESS TYPE in the address section in my admin as you can see on this picture where an address is submitted in an checkoutform (the address type should be the shipping address): enter image description here
this is the code of my models.py:
from django.db import models
from billing.models import BillingProfile
ADDRESS_TYPES = (
('billing', 'Billing'),
('shipping', 'Shipping'),
)
# Create your models here.
class Address(models.Model):
billing_profile = models.ForeignKey(BillingProfile)
address_type = models.CharField(max_length=120, choices=ADDRESS_TYPES)
address_line_1 = models.CharField(max_length=120)
address_line_2 = models.CharField(max_length=120, null=True, blank=True)
city = models.CharField(max_length=120)
country = models.CharField(max_length=120)
state = models.CharField(max_length=120)
postal_code = models.CharField(max_length=120)
def __str__(self):
return str(self.billing_profile)
and this is the views.py:
from django.shortcuts import render, redirect
from django.utils.http import is_safe_url
# CRUD create update retrieve delete
from billing.models import BillingProfile
from .forms import AddressForm
def checkout_address_create_view(request):
form = AddressForm(request.POST or None)
context = {
"form": form
}
next_ = request.GET.get('next')
next_post = request.POST.get('next')
redirect_path = next_ or next_post or None
if form.is_valid():
instance = form.save(commit=False)
billing_profile, billing_profile_created = BillingProfile.objects.new_or_get(request)
if billing_profile is not None:
instance.billing_profile = billing_profile
instance.address_type = request.POST.get('address_type', 'shipping')
instance.save()
else:
print("Error here")
return redirect("cart:checkout")
if is_safe_url(redirect_path, request.get_host()):
return redirect(redirect_path)
else:
return redirect("cart:checkout")
return redirect("cart:checkout")
This rule should do the trick in views.py, but unfortunately not showing in the admin (as seen on the picture :( :
instance.address_type = request.POST.get('address_type', 'shipping')
Does someone has advice?

django prevent empty model being saved

Is there a way to stop a model in django allowing an empty model to be saved?
e.g. I have a simple contact form
class Contact(models.Model):
alphabetical = RegexValidator(r'^[a-zA-Z]*$', 'Only alphabetical characters
are allowed', 'Invalid input')
name = models.CharField(max_length=200, validators=[alphabetical])
email = models.EmailField(validators=[EmailValidator, ])
subject = models.CharField(max_length=200)
message = models.CharField(max_length=250)
created_date = models.DateTimeField(auto_now_add=True)
How can I prevent an empty model being saved? e.g. in the django shell I can do
contact = Contact()
contact.save()
This gives a model with all blank values saved.
for validation you have to use django.forms. django forms will manage the validation part:
for eg: if your model.py is:
class Contact(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
subject = models.CharField(max_length=200)
message = models.CharField(max_length=250)
created_date = models.DateTimeField(auto_now_add=True)
now create a view in views.py :
from django.forms import modelformset_factory
from django.shortcuts import render
from myapp.models import Contact
def manage_contacts(request):
ContactFormSet = modelformset_factory(Contact, fields=('name', 'email', 'subject', 'message'))
if request.method == 'POST':
formset = ContactFormSet(request.POST)
if formset.is_valid(): # check the validation for blank fields
formset.save()
# do something.
else:
formset = ContactFormSet()
return render(request, 'manage_contacts.html', {'formset': formset})
create a template in templates/manage_contacts.html:
<form method="post">
{{ formset }}
</form>

NOT NULL constraint failed: IntegrityError

Trying a django project from the documentations.
This is my Models.py I am trying to make a simple employee goals management system. I have also used DRF and serializers, integrated swagger for only doing 'GET' of the models below. I have removed (commented out) all ForeignKey and ManyToMany Fields yet, when I add modify the goal or project I get this error. I cant seem to solve this, please help.
class Department(models.Model):
department_name = models.CharField(max_length=200)
department_location = models.CharField(max_length=200)
department_region = models.CharField(max_length=200)
department_site = models.CharField(max_length=200)
department_job_titles = models.CharField(max_length=200)
def __str__(self):
return self.department_name
class Employee(models.Model):
#department_name = models.ManyToManyField(Department)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email_id = models.CharField(max_length=100)
#employee_id = models.IntegerField()
supervisor_name = models.CharField(max_length=100)
designation = models.CharField(max_length=100)
doj = models.DateTimeField('date joined')
def __str__(self):
return self.first_name
class Objectives(models.Model):
objective_name = models.CharField(max_length=200)
#employee = models.ManyToManyField(Employee)
def __str__(self):
return self.objective_name
class Project(models.Model):
#employee = models.ManyToManyField(Employee)
project_name = models.CharField(max_length=200)
def __str__(self):
return self.project_name
class Goals(models.Model):
goal_id = models.IntegerField()
goal_name = models.CharField(max_length=200)
#department = models.ManyToManyField(Department)
role = models.CharField(max_length=200)
#objective_id = models.ManyToManyField(Objectives)
goal_start = models.DateTimeField('date goal added')
goal_end = models.DateTimeField('date goal ends')
#employee = models.ManyToManyField(Employee)
def __str__(self):
return self.goal_name
This is my views.py
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 Employee
from .models import Goals
from .models import Objectives
from .models import Department
from .models import Project
from .serializers import EmployeeSerializer
from .serializers import ProjectSerializer
from .serializers import GoalsSerializer
from .serializers import ObjectivesSerializer
from .serializers import DepartmentSerializer
from django.http import HttpResponse
from rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title='UpYourGame API')
#just a view if someone hits the index
def index(request):
return HttpResponse("Hello and Welcome to UpyourGame")
# this will be the URL /employee/
class Employee(APIView):
def get(self, request):
employee = Employee.objects.all()
serializer = EmployeeSerializer(employee, many=True)
return Response(serializer.data)
class Project(APIView):
def get(self, request):
project = Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
class Goals(APIView):
def get(self, request):
goals = Goals.objects.all()
serializer = GoalsSerializer(goals, many=True)
return Response(serializer.data)
class Objectives(APIView):
def get(self, request):
objectives = Objectives.objects.all()
serializer = ObjectivesSerializer(objectives, many=True)
return Response(serializer.data)
#class Company(APIView):
# def get(self, request):
# company = Company.objects.all()
# serializer = CompanySerializer(company, many=False)
# return Response(serializer.data)
class Department(APIView):
def get(self, request):
department = Department.objects.all()
serializer = DepartmentSerializer(Department, many=True)
return Response(serializer.data)
This is myproject/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from enterprise import views
urlpatterns = [
url(r'^$', views.schema_view, name='schema_view'),
url(r'^enterprise/', include('enterprise.urls')),
url(r'^admin/', admin.site.urls),
url(r'^employee/', views.Employee.as_view()),
url(r'^goals/', views.Goals.as_view()),
url(r'^department/', views.Department.as_view()),
url(r'^department/', views.Department.as_view()),
url(r'^objectives/', views.Objectives.as_view()),
url(r'^project/', views.Project.as_view()),
]
This is my serializers.py
from rest_framework import serializers
from .models import Employee
from .models import Goals
from .models import Objectives
from .models import Department
from .models import Project
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
#class EmployeeDetailsSerializer(serializers.ModelSerializer):
# class Meta:
# model = EmployeeDetails
# fields = '__all__'
class ObjectivesSerializer(serializers.ModelSerializer):
class Meta:
model = Objectives
fields = '__all__'
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Department
fields = '__all__'
#class CompanySerializer(serializers.ModelSerializer):
# class Meta:
# model = Company
# fields = '__all__'
class GoalsSerializer(serializers.ModelSerializer):
class Meta:
model = Goals
fields = '__all__'
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
The SQLlite DB was corrupt due to too many migrations, it can happen. I deleted SQLlite and all my migrations, I retried migrate, makemigrate and sqlmigrate, it resolved the issue.
If you run into a similar issue in a dev environment please try the following
1. Delete all your migrations in the migrations folder
2. Delete db.sqlite3
3. Run python manage.py migrate
4. Run python manage.py makemigrations
5. Run python manage.py sqlmigrate appname 0001
This will fix this issue.

Resources