model = User in Meta class of django - python

I am trying to read a code that concerns about user registration form. The code has a Meta class which I know what it does, but assigning model to User doesn't give sense to me. Can you please explain it?
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User # explain?
fields = ["username", "email", "password1", "password2"]

Django relies on Inner Classes to provide metadata, Your UserRegisterForm needs to know when you call UserRegisterForm.save() what database table to send this form data to.
This is why you need model = User inside your Meta class, so the form knows where to go about storing.

Related

Is it better to make custom registration with editing Django UserCreationForm class or make it on a new table and class?

I wanted to make a Django authentication but I was confused about wichone is better?
is it is better to edit the venv/Lib/site-packages/django/contrib/auth/forms.py file and make my custom form and edit DB on venv/Lib/site-packages/django/contrib/auth/models.py or it's better to make my authentication system with model and views and forms on my application?
You don't need to add django's files. you can inherit there properties.
for example let's say you want to use User model of Django. you can do that in your models.py like following. here you ll get all the fields of Abstract User like first_name, email, passwords etc but you can add your own fields such as technoking in below example
from django.db import models
from django.contrib.auth.models import AbstractUser
import uuid
class User(AbstractUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
technoking = models.BooleanField(default=False)
objects = UserManager()
def __str__(self):
return self.username

How to POST an entity specifiying an integer foreign key in django rest framework

I am building a chat application with django rest framework and I m currently working on messages. This are my models:
from django.db import models
from django.contrib.auth.models import User
class Message(models.Model):
text = models.CharField(max_length=500)
datetime = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE);
I am using the Django auth User model. This is my ModelViewSet for the messages:
class MessageViewSet(ModelViewSet):
queryset = Message.objects.all()
serializer_class = MessageSerializer
And these are my serializers:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username']
class MessageSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model = Message
fields = '__all__'
And this is my API:
The code I've written so far works really well for the GET functionally I want. I want for each message to get the username of the user it belongs to. But now I want the following thing: when I POST a new message, I want to be able to specify which user it belongs to by specifying the user's id. Right now I have only the "text" field in the POST section. I need to add a "user" field which takes in an integer (the user primary key) to specify which user the message belongs to. How should I refactor my code in order to do that?
Because you've overridden the user field and set it to read_only=True, you cannot set a user when you're creating/updating a model.
If you just need the user's username, I'd suggest you to add a username field into MessageSerializer directly instead:
class MessageSerializer(serializers.ModelSerializer):
username = serializers.CharField(source='user.username', read_only=True)
class Meta:
model = Message
fields = '__all__'
Now you'll get this payload instead:
{
"id": 1,
"user": 1,
"username": "timi",
...
And you should be able to set a user id now.

Trying to add custom fields to users in Django

I am fairly new to django and was it was going well until this.
i'm trying to add fields 'address' and 'phone_number' to users (create custom user basically) but i keep getting this error like this...
File "C:\Users\will5\Desktop\City\city_info\forms.py", line 5, in <module>
class UserForm(forms.ModelForm):
File "C:\Users\will5\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\django\forms\models.py", line 257, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (phone_number, address)
specified for User
this is models
...
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone_number = models.IntegerField(default=0)
address = models.CharField(max_length=150)
...
this is in my forms
from django.contrib.auth.models import User
from django import forms
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'email', 'password', 'address', 'phone_number']
I also read that in order to fix this problem i will have to restart my project by creating the custom user and migrating and i don't wanna do that.
The problem is that you are still importing the built in user model
You can fix it by replacing
from django.contrib.auth.models import User
with
from django.contrib.auth import get_user_model
User = get_user_model()
This assumes that you have set AUTH_USER_MODEL = 'yourapp.User' in your settings.
As you have read in the docs, it is extremely difficult to switch to a custom user model after the project has started, there isn't an easy solution to this. If you can't restart your project, perhaps you could create a Profile model with a OneToOneField to the default User instead.

How to update a user profile field using rest API

I am new to django and very confused. I am using django as the backend API for my angular application.
I want to add few more details to the User model so I added the following to my models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
company_name = models.CharField(max_length=100)
I am using an application to add rest authentication support: https://github.com/Tivix/django-rest-auth
Using this application I can edit a users profile with this URL doing a POST request: http://localhost:8080/rest-auth/user/
Question
How can I update the custom field company_name? while editing a users profile?
What I've tried
I tried to override the UserDetailsSerializer that the application provides but it isn't having any effect.
This is what I tried adding to my applications serializers.py
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserProfile
fields = ('company_name',)
class UserDetailsSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer(required=True)
class Meta:
model = models.User
fields = ('id', 'username', 'first_name', 'last_name', 'profile')
If you are using django rest framework, then you basically want to have an update method on your view class for UserProfile that takes in the user id as a request param. Then in that method you want to use the ORM to get a model object for the given userprofile id, set the property that was also passed as a param, and save the changed model object. Then generate a success response and return it.
You can read more about how to do this here: http://www.django-rest-framework.org/api-guide/views/

Django: how to including inline model fields in the list_display?

I'm attempting to extend django's contrib.auth User model, using an inline 'Profile' model to include extra fields.
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
class Profile(models.Model):
user = models.ForeignKey(User, unique=True, related_name='profile')
avatar = '/images/avatar.png'
nickname = 'Renz'
class UserProfileInline(admin.StackedInline):
model = Profile
class UserProfileAdmin(UserAdmin):
inlines = (UserProfileInline,)
admin.site.unregister(User)
admin.site.register(User, UserProfileAdmin)
This works just fine for the admin 'Change User' page, but I can't find a way to add inline model fields in the list_display. Just specifying the names of Profile fields in list_display give me an error:
UserProfileAdmin.list_display[4], 'avatar' is not a callable or an attribute of 'UserProfileAdmin' or found in the model 'User'.
I can create a callable which looks up the user in the Profile table and returns the relevant field, but this leaves me without the ability to sort the list view by the inline fields, which I really need to be able to do.
Any suggestions?
You've mentioned the only solution - creating a callable. There's currently no other way to do it, and yes this does mean you can't sort by that column.

Categories