User signup system in Django with custom fields - python

I am trying to make a user Signup system along with his profile.
my models.py:
class myCustomeUser(AbstractUser):
username = models.CharField(max_length=50, unique="True", blank=False)
password = models.CharField(max_length=200, blank=False)
USERNAME_FIELD = 'username'
class Profile(models.Model):
user = models.OneToOneField(myCustomeUser, null=True, on_delete=models.CASCADE)
bio = models.TextField()
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/profile/")
my forms.py:
class SignUpForm(ModelForm):
class Meta:
model = Profile
fields = '__all__'
my views.py:
class index(generic.CreateView):
form_class = SignUpForm
template_name = 'index.html'
Now here my problem is, the form gives me an option to choose any user (with dropdown) to create a profile.... but I want to create a user also on that page (not pick an option from dropdown). How can I try for that?

Your need to connect your user creation form with Django post_Save signals.
I will point out a tutorial that can assist you
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html

Your signup form should use myCustomeUser
So that you create a user first
Then.with the help of "signals" you can create profiles automatically every time a user is created

Related

'project.Account' has no ForeignKey to 'project.Object': How to link an account model to the objects of a project?

I am trying to create an announcement website (All) that can be visible to others (the Users, for which I added an Account). For this I wanted to modify a little the user profile to add fields like telephone, email address...
So I modified admin.py:
from django.contrib import admin
from .models import Todo, Account
from django.contrib.auth.models import User
class AccountInline(admin.StackedInline):
model = Account
can_delete = False
verbose_name_plural = 'Accounts'
class TodoAdmin(admin.ModelAdmin):
readonly_fields = ('created',)
inlines = (AccountInline, )
admin.site.unregister(User)
admin.site.register(Todo, TodoAdmin)
But got back:
<class 'todo.admin.AccountInline'>: (admin.E202) 'todo.Account' has no ForeignKey to 'todo.Todo'.
So I added a ForeignKey to Todo with account = models.ForeignKey(Account, on_delete=models.CASCADE):
from django.db import models
from django.contrib.auth.models import User
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email = models.CharField(max_length=100)
firstname = models.CharField(max_length=30)
lastname = models.CharField(max_length=50)
company = models.CharField(max_length=5)
def __str__(self):
return self.user.username
class Todo(models.Model):
title = models.CharField(max_length=100)
datetime = models.DateTimeField()
memo = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True)
datecompleted = models.DateTimeField(null=True, blank=True)
important = models.BooleanField(default=False)
user = models.ForeignKey(User, on_delete=models.CASCADE)
account = models.ForeignKey(Account, on_delete=models.CASCADE)
def __str__(self):
return self.title
But I still have the error, and I don't have any Users in the admin panel anymore
You accidentally wrote unregister for Users in your admin.py file. It should be admin.site.register(User)
You misinterpretted the error: the error states that you don't have a foreign key in your Account model to Todo.
This means your inline admin code isn't correct as it's expecting the other way around.

Django admin page not showing user models

My admin page is working fine except when logged in it is not showing any user models. It is hindering my work as I cannot manage users.
I have made custom models as shown below.
Database is MySQL.
models.py
class User(AbstractUser):
is_customer = models.BooleanField(default=False)
is_restaurant = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
food_pref = models.CharField(max_length=10, default='veg')
class Restaurant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
restaurant_name = models.CharField(max_length=100, blank=False)
Regisrar your models inadmin.py file.
from . models import Model_Name
Then you can register your models in two ways:
I) admin.site.register(Model_Name)
II)
#admin.register(Model_Name)
Class Xyz(admin.ModelAdmin):
pass
Second method gives you more flexibility like list_display, list_filter, date_hierarchy, etc. for customising your Admin section/site.
You can look more about customising admin site at https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#module-django.contrib.admin
Have You registered them in admin.py?
from .models import ModelName
admin.site.register(ModelName)

How can I validate my forms or views in Django so that they can only edit the User Model only to those that belong to that data?

I have 2 models that I will allow users to edit separately, one is called User(Django default auth) and the other is UserProfile.
models.py (UserProfile)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to='avatar', default='avatar/default.png')
header = models.ImageField(upload_to='header', default='header/default.png')
bio = models.TextField(max_length=140, blank=True)
website = models.URLField(max_length=200, blank=True)
location = models.CharField(max_length=30, blank=True)
date_birth = models.DateField(null=True, blank=True)
views.py
class UserUpdateView(generic.UpdateView):
"""
This view is for editing only the User model. /edit/
"""
model = User
slug_field = 'username'
form_class = UserForm
template_name = 'user/user_edit.html'
First, use the LoginRequiredMixin mixin so that only logged-in users can access the view.
Then, override the get_object method, and return the model instance you want to edit.
You don't need the username in the URL any more, so you can remove slug_field = 'username'.
from django.contrib.auth.mixins import LoginRequiredMixin
class UserUpdateView(LoginRequiredMixin, generic.UpdateView):
model = User
form_class = UserForm
template_name = 'user/user_edit.html'
def get_object(self):
return self.request.user
If you have a similar view for editing the user profile you would return self.request.user.userprofile instead.

How to save forms field in django

i have some fields in my django models.
class Product(models.Model):
user=models.ForeignKey(User)
product_name = models.CharField(max_length=50)
product_cost = models.IntegerField(default=0,null=True, blank=True)
product_description = models.TextField(null=True, blank=True)
quantity = models.IntegerField(default=0,null=True, blank=True)
product_image = models.FileField(upload_to='images/',blank=True,null=True,)
coupon_code = models.CharField(max_length=50)
time = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.product_name or u''
when i use form to save all the data from front end in my database i can do this.
class DocumentForm(forms.ModelForm):
class Meta:
model = Product
fields = ('user','product_name','product_image','product_cost','product_description','product_description','coupon_code')
Problem is this i don't want to allow user to fill user data from front-end.when user save data it save request.user to user.
I am new to work with forms so facing some issues.
Please help me how can i do this.
Thanks in advance.
In fields you have to remove user:
so it will look like this:
class DocumentForm(forms.ModelForm):
class Meta:
model = Product
fields = ('product_name','product_image','product_cost','product_description','product_description','coupon_code')
and in your views.py when you save the data from the form you have write something like this:
user = request.user
in this case user will be saved if he is authenticated.
If you want that not authenticated user could fill the form too, you have to change in your model.py Product class from:
user=models.ForeignKey(User)
to:
user=models.ForeignKey(User, null=True)
then not authenticated user will be NULL.

Django REST Framework: change field names

My Django application provides readonly api access to the users of the site. I created a user profile model and use it in the serializer of the user model:
Model:
# + standard User Model
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
display_name = models.CharField(max_length=20, blank=True)
Serializer:
class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserProfile
fields = ('display_name',)
class UserSerializer(serializers.HyperlinkedModelSerializer):
userprofile_set = UserProfileSerializer(many=False, label='userprofile')
class Meta:
model = User
fields = ('id', 'username', 'userprofile_set')
This works but the field userprofile_set looks ugly. Is it possible to change the field name?
To complement your answer, you can also make use of relationships' related names:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True, related_name='profiles')
display_name = models.CharField(max_length=20, blank=True)
that way you can also use this in your code:
user = User.objects.last() #some user
user.profiles.all() #UserProfiles related to this user, in a queryset
user.profiles.last() #the last UserProfile instance related to this user.
May I recommend that you turn that ForeignKey into a OneToOneField? that way an user can have one and just one user profile, and you don't need to establish uniqueness:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
display_name = models.CharField(max_length=20, blank=True)
Oh, I can name the variable userprofile_set as I like. First I tested the name userprofile which conflicted. If I name the field profile it works. :)
class UserSerializer(serializers.HyperlinkedModelSerializer):
profile = UserProfileSerializer(many=False, label='userprofile')
class Meta:
model = User
fields = ('id', 'username', 'profile')

Categories