In Django I have replaced the user model using (AbstractUser).
Then in the admin panel area the fields are unordered. When generating a new user, the password is not encrypted, the user is saved with the password unencrypted. But then I can't access the admin panel. Returning error the username or password do not match.
In model.py
# from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser
from django.db import models
# UserModel = get_user_model()
class UserAgent_mod(AbstractUser):
phone_number = models.CharField(
max_length=9,
blank=True,
null=True,
)
profile_image = models.ImageField(
upload_to='photos_user_agent',
)
manage_properties = models.ManyToManyField(
to='property_app.Property_mod',
related_name='manage_properties',
blank=True
)
def __str__(self):
return f'{self.first_name} {self.last_name}'
class Meta:
verbose_name='User Agent'
verbose_name_plural = 'Users Agents'
In admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
UserModel = get_user_model()
#admin.register(UserModel)
class UserAgentAdmin(admin.ModelAdmin):
list_display = (
'username',
'first_name',
'last_name',
'phone_number',
'email',
)
list_filter = (
'first_name',
'last_name',
)
in settings.py
AUTH_USER_MODEL= 'user_agent_app.UserAgent_mod'
Demo result of the problem
put the following code in your admin.py file:
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAgent_mod as BaseUserAdmin
class UserAgentAdmin(BaseUserAdmin):
fieldsets = BaseUserAdmin.fieldsets
ADDITIONAL_USER_FIELDS = (
(None, {'fields': ('phone_number','profile_image','manage_properties')}),
)
fieldsets = fieldsets + ADDITIONAL_USER_FIELDS
list_display = (
'username',
'first_name',
'last_name',
'phone_number',
'email',
)
list_filter = (
'first_name',
'last_name',
)
admin.site.register(get_user_model, UserAgentAdmin)
Whan you use AbstarctUser and you need to add users via the django admin panel, you should also use the UserCreationForm and UserChangeForm, so the password will be encrypted.
To do so, make a forms.py file in your users application and add the following code to it:
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import UserAgent_mod
class UserCreationForm(UserCreationForm):
# If you want to give superuser privileges to the staff users, override the save method
def save(self, commit=True):
user = self.instance
if user.is_staff:
user.is_superuser = True
return super().save(commit=True)
class Meta:
model = UserAgent_mod
fields = ('email', 'first_name', 'last_name') # add any other field you want
class UserChangeForm(UserChangeForm):
class Meta:
model = UserAgent_mod
fields = ('email', 'first_name', 'last_name') # add any other field you want
Also add the below code to your admin.py:
(change the fields as you want to)
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .forms import UserCreationForm, UserChangeForm
from .models import UserAgent_mod
class UserAdmin(UserAdmin):
add_form = UserCreationForm
form = UserChangeForm
model = UserAgent_mod
list_display = ('email', 'is_staff', 'is_active',)
list_filter = ('email', 'is_staff', 'is_active',)
fieldsets = (
(None, {'fields': ('email', 'password', 'first_name', 'last_name')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'first_name', 'last_name', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
admin.site.register(UserAgent_mod, UserAdmin)
You can read more about AbstractUser in this article.
Related
I would like to associate a post with a logged-in user, a React, and Django app.
I have tried this, and am getting an unauthorized error,
settings.py
REST_FRAMEWORK = {
# 'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated'
# ],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('JWT',),
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'AUTH_TOKEN_CLASSES': (
'rest_framework_simplejwt.tokens.AccessToken',
)
}
my serializers.py
class PoultryCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Poultry
fields = ('title', 'price', 'category', 'description',
'image', 'county', 'subcounty', 'location', 'contact')
read_only_fields = ['seller']
views.py
#api_view(["POST"])
#authentication_classes([authentication.TokenAuthentication])
#permission_classes([permissions.IsAuthenticated])
def poultrycreate(request):
print(request.user)
parser_classes = (MultiPartParser, FormParser)
serializer = PoultryCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save(seller=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
# print('error', serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I was trying to hash the password but it turns out that my entity file is not being included in the cakephp. Can someone help me why it is happening ???
When i run debug(get_included_file()); it does not show my User.php entity file.
and my User.php file content is :
<?php
declare(strict_types=1);
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Auth\DefaultPasswordHasher;
class User extends Entity
{
protected $_accessible = [
'email' => true,
'password' => true,
'created' => true,
'modified' => true,
];
protected $_hidden = [
'password',
];
public function _setPassword($password) : ?string {
if(strlen($password) > 0 ){
return (new DefaultPasswordHasher())->hash($password);
}
}
}
I am trying to implement auth login and register cakephp 3.7.4
I have used following code for UsersController add method
public function add()
{
$this->viewBuilder()->setLayout('login');
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$post = $this->request->getData();
$post['created'] = date('Y-m-d H:i:s');
$post['modified'] = date('Y-m-d H:i:s');
$user = $this->Users->patchEntity($user, $post);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'login']);
}
$this->Flash->error(__('Unable to add the user.'));
}
$this->set('user', $user);
}
But it can't save password in Hash Format
I have also create entity and used this function but it also not helped me
class User extends Entity
{
protected $_accessible = [
'email' => true,
'password' => true
];
protected $_hidden = [
'password'
];
protected function _setPassword($password){
return(new DefaultPasswordHasher)->hash($password);
}
}
I installed a fresh Cake 3.7.4 installation, baked a users table, users controller and users table/entity. The following code for the User Class successfully hashed the password before it is written to the database. Please compare it with your code.
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;
class User extends Entity
{
protected $_accessible = [
'email' => true,
'password' => true,
'modified' => true,
'created' => true
];
protected $_hidden = [
'password'
];
protected function _setPassword($password)
{
return (new DefaultPasswordHasher())->hash($password);
}
}
Just use parenthesis around DefaultPasswordHaser():
return(new DefaultPasswordHasher())->hash($password);
I'm using the excellent CakeDC Tags plugin on my Solutions model:
class Solution extends AppModel {
public $actsAs = array(
'Tags.Taggable',
'Search.Searchable',
);
}
I have a SolutionsController::search() method:
App::uses('AppController', 'Controller');
class SolutionsController extends AppController {
public $components = array(
'Paginator',
'Search.Prg',
);
public $presetVars = true; // using the model configuration ('Search' plugin)
public function search() {
$this->Prg->commonProcess();
$this->Paginator->settings['conditions'] = $this->Solution->parseCriteria($this->Prg->parsedParams());
$solutions = $this->Paginator->paginate();
if (!empty($solutions)) {
$this->Session->setFlash('Solutions found');
} else {
$this->Session->setFlash('No solutions found');
}
$this->set('solutions', $solutions);
$this->render('index');
}
I'm trying to write a test for this method:
App::uses('SolutionsController', 'Controller');
class SolutionsControllerTest extends ControllerTestCase {
public $fixtures = array(
'app.solution',
'plugin.tags.tag'
);
public function testSearchForOneResultShouldOutputText() {
$data = array('search' => 'fiery');
$result = $this->Solution->search($data);
debug($result);
$expected = array(
'id' => 3,
'name' => 'fiery-colored horse',
'shortdesc' => 'war',
'body' => 'it was granted to the one seated on it..',
'category_id' => 3,
'created_by' => 1,
'modified_by' => 1,
'created' => '2014-02-14 21:28:46',
'modified' => '2014-02-14 21:28:46'
);
$this->assertContains($expected);
}
}
I'm getting this error when running the test:
Missing Database Table
Error: Table tags for model Tag was not found in datasource test.
I've tried copying the plugin Tag fixture to my app Test/fixtures folder and including it as an app fixture. I can't get my test to run. How do I get my test to see the tags fixture from app\Plugin\tags\Test\Fixture\TagFixture.php and run?
Problem turned out to be my SolutionsFixture, which imported the table schema and the records, then also included a $records array (oops). Re-baking this fixture to import neither schema nor records resolved the error.
I'm trying to build an invitation system with CakePHP. I have Invitation model which hasMany People, and Person hasOne and belongsTo Invitation. I believe the relationships are working, since my Invitation index view can properly access and display its associated People through the Invitation model. But heres what the relationship rules look like:
class Invitation extends AppModel {
var $name = 'Invitation';
var $hasMany = array(
'People' => array(
'className' => 'Person',
'foreignKey' => 'invitation_id',
'dependent'=> true
)
);
...
}
class Person extends AppModel {
var $name = 'Person';
var $hasOne = 'Invitation';
var $belongsTo = 'Invitation';
...
}
UPDATED MODEL RELATIONSHIPS:
class Invitation extends AppModel {
var $name = 'Invitation';
var $hasMany = array('Person');
...
}
class Person extends AppModel {
var $name = 'Person';
var $belongsTo = array('Invitation');
...
}
In my Invitation add function, however, I am having trouble saving the data for new People. I want to simultaneously add one invitation and two people.
Heres my add function:
function add() {
$this->autoRender = false;
if($this->RequestHandler->isAjax()) {
$this->layout = 'ajax';
if(!empty($this->data)) {
$this->Invitation->create();
if($this->Invitation->saveAll($this->data)) {
//debug($this->data);
$this->Session->setFlash('Saved');
$this->redirect('invitations/add_invitations');
} else {
echo('Didnt save<br />');
}
}
}
}
Here is the output of my debug($this->data):
Array
(
[Invitation] => Array
(
[code] => 001
[password] => 85c8a3735499bf91d25e5960ab4ed9deeb0b457e
[type] => 1
[num_people] => 2
)
[Person] => Array
(
[0] => Array
(
[fname] => Jane
[lname] => Doe
)
[1] => Array
(
[fname] => John
[lname] => Doe
)
)
)
I don't get any errors. the Invitation data is saved properly, but the people are not.
UPDATE: I finally got this working with the above updated model relationships. Obviously the hasOne & belongsTo rules in the Person model were conflicting. After that I made a mistake (an embarrassing one) that was preventing saving to related the related Person model:
In the Invitation model, I hade $hasMany = array('People'); when it should have been $hasMany = array('Person').
I also had to change the configuration of my database to use InnoDB as the default, so that was certainly a necessary fix.
var $hasOne = 'Invitation';
var $belongsTo = 'Invitation';
These relations to the same model should have different Aliases otherwise Cake will get confused, as I did trying to unpick it. See http://book.cakephp.org/view/1046/Multiple-relations-to-the-same-model