I am trying to develop a form where the user would be able to achieve this :
Database
So the form would have :
a TextField for the name
a TextField for the description
a TextField for the addresses that would be entered by the User as a list
According to you, what would be the most appropriate approach to do so?
Thank you very much !
from django.db import models
class Address(models.Model):
address = models.TextField()
class UserModel(models.Model):
user = models.CharField(max_length=255, required=True)
description = models.TextField()
addresses = models.ManyToMany(Address)
You can create the models and integrate them by the above code. One user can set multiple addresses to him, on the other side, one address can be assigned into many users. so Many To Many relationships can be fruitful to this scenario.
Related
I want to extend the Base Abstract User Model and this is the extended model:
class Student(AbstractUser):
birth = models.DateField(default=datetime.date.today)
street = models.CharField(max_length=25)
street_number = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)])
city = models.CharField(max_length=20)
province = models.CharField(max_length=20)
code = models.IntegerField(validators=[MinValueValidator(0, MaxValueValidator(9999))])
address = str(street) + str(street_number) + str(city) + str(code) + str(province)
But I get this message popup:
It is impossible to add a non-nullable field 'password' to student without specifying a default. This is because the database needs something to populate existing rows.
However I haven't added a new password field and all the existing password fields (for the superuser) already have a value. What should I do?
When I add a default value and try to migrate it, it complains that there is no such table as 'mainApp_student'.
You don't want to do that. You want a User model (you already have one that Django provides, no need to extend it for now), and a Student model that has a OneToOne relationship with the User model.
Conceptually:
User: models a user of your application and its authentication and permissions
Student: the representation of a person attending classes, with a name, a birthday etc..., also has a user to access your application which is unique to them.
In code:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE))
# ... other fields: birth address etc...
This page of the docs explains it well, especially the Employee example given:
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
I'm trying to add a choices option to a ForeignKey field. But that prevents the input form from getting validated.
I'm not sure if you can use choices in ForeignKey field, but how else would you provide human readable output for the choices?
I don't want the user to be able to choose from all groups and don't want to display the actual group name as it contains additional info for the admins, that shouldn't be visible to the user, for cosmetic reasons.
Any idea how to achieve that would be greatly appreciated.
Here is my code:
The model:
from django.contrib.auth.models import Group as DjangoGroup
class Category(models.Model):
created_by = models.ForeignKey('auth.User', on_delete=models.PROTECT, related_name='category_author')
last_edited_by = models.ForeignKey('auth.User', on_delete=models.PROTECT, related_name='category_editor')
name = models.CharField(max_length = 100)
privileges = models.ForeignKey('auth.Group', on_delete=models.PROTECT, blank=True, null=True, choices=((DjangoGroup.objects.get(pk=5), 'Test group'),))
The Form:
from django import forms
from .models import *
class CategoryForm(forms.ModelForm):
class Meta:
model = Category
exclude = ('created_by', 'last_edited_by',)
With this code the form gives the desired option 'Test group', but when I try to submit it I get the following error:
Select a valid choice. TestGroup(just for testing purposes) is not one of the available choices.
with 'TestGroup(just for testing purposes)' being the actual group name that I am trying to hide from the user.
I hope you can understand what I am trying to achieve. Am I on the right track or is there a different way to do this?
Thanks in advance for any answer
So I have been searching all around the internet for a full example of how to user AbstractUser when u have at least 2 different models. Didn't find anything conclusive.. at least that would work on latest version of Django (2.0.1).
I have 2 models, teacher and student, and registration needs to be different. Besides username, email, name and surname, I need for example, for the student, to upload a profile picture, email, phone, student_ID. And for teacher, bio, academic title and website. Did I start good ? What is the right approach ?
class Profile(AbstractUser):
photo = models.ImageField(upload_to='students_images')
email = models.EmailField()
phone = models.CharField(max_length=15, )
class Student(Profile):
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
def __str__(self):
return self.name
class Teacher(Profile):
academic_title = models.CharField(max_length=30)
bio = models.TextField()
website = models.URLField(help_text="E.g.: https://www.example.com", blank=True)
Your goals can be accomplished using a 'Profile' pattern. You don't necessarily need to use a custom user model for this. But you need to have a single common model to for authentication; you can use the builtin django user for this or a custom class... Your Student and Teacher models should be OnetoOne relationships. This is the recommended solution per the documentation.
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
In your case, you may do something like this:
class StudentProfile(models.Model):
user = models.OneToOneField('User', related_name='student_profile')
# additional fields for students
class TeacherProfile(models.Model):
user = models.OneToOneField('User', related_name='teacher_profile')
# additional fields for teachers
Then you can create your registration forms based on these profile models.
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (...)
class TeacherRegistrationForm(forms.ModelForm):
class Meta:
model = TeacherProfile
fields = (...)
You can create the user instance to which the profile is related to at the same time you create the profile. You might do this with formsets, for example.
add
class Meta:
abstract = True
to profile model
and change AbstractUser to models.Model
I'm making a Django form to update users membership to a website. I want to be able to store phone numbers. I found django-phonenumber-field which is great. The only problem is that the form I created for the user to enter their phone number is too specific. If the user doesn't enter their number as "+99999999" then they get an input error. I would like for the user to be able to enter their number a variety of ways: 999-999-9999, 9-999-9999, (999)999-9999, etc. What's the best way to accomplish this?
My code:
models.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
class Member(models.Model):
"""defines a member for annual registration"""
name = models.CharField(max_length=255)
mailing_address = models.CharField(max_length=255)
home_phone = PhoneNumberField()
other_phone = PhoneNumberField(blank=True)
email = models.EmailField()
forms.py
from django import forms
from .models import Member
class MembershipForm(forms.ModelForm):
"""form for renewing membership"""
class Meta:
model = Member
fields = ('name',
'mailing_address',
'home_phone',
'other_phone',
'email',
)
Thank you for any help!
That field definition is a custom field in Django. You can create your own custom fields. I would recommend getting the code for the PhoneNumberField, which is open source, and subclassing it to you own field MyPhoneNumberField. Override the validation logic to be as you wish. See the details of how these things work at
https://docs.djangoproject.com/en/1.11/ref/forms/validation/
I created this class Person, but looking at the Django User model they seem to be very similar.
In this case, should I be using it ? Or should I keep with my own model ?
My major concern is that, I don't want to my users login into localhost:8000/admin page and start to mess with my system and other users data.
class Person(models.Model):
full_name = CharField(max_length=255)
address = CharField(max_length=255)
city = CharField(max_length=255)
country = CharField(max_length=2, choices=CountryChoices, default='')
gender = CharField(max_length=1, choices=GenderChoices, default='')
email = EmailField()
password = CharField(max_length=255)
started = DateTimeField(auto_now_add=True, auto_now=False)
updated = DateTimeField(auto_now_add=False, auto_now=True)
#how it's show in admin
def __unicode__(self):
return smart_unicode(self.full_name + ' (' + self.email + ')')
You should not create this model. Apart from any considerations of efficiency, it looks as though you are storing passwords in clear text, which is an absolute no.
Instead, extend AbstractBaseUser and set AUTH_USER_MODEL to point to that model. If you define an is_staff boolean field, your users will not be permitted to log into the admin site as long as they have that field set to False.
If you're not looking to give you users access to the admin, there's nothing wrong with using the model that you've included here.
If you wanted to use the auth User model, you certainly could. If you want to add the User model to your model later on, you could tie them together with a ForeignKey.
this is wrong. some of this field are in User model. and it is better to use User model and define aditional field in your model. take a look at Storing additional information about users.
Also you can develope your own login system like this.