how to store phone_number fields in Flask model - flask

In Django I'd use PhoneNumberField like this
phone_number = PhoneNumberField(
unique=True,
blank=False,
null=True
)
I need to use the phone number for logging in.
so what's the best practice in Flask (I'm new to it).

WTForms is popularly used w/ flask. Field Enclosures allow you to handle phone numbers such as the following:
class TelephoneForm(Form):
country_code = IntegerField('Country Code', [validators.required()])
area_code = IntegerField('Area Code/Exchange', [validators.required()])
number = StringField('Number')
class ContactForm(Form):
first_name = StringField()
last_name = StringField()
mobile_phone = FormField(TelephoneForm)
office_phone = FormField(TelephoneForm)
source -> https://wtforms.readthedocs.io/en/2.3.x/fields/
control + f the page for word phone

Related

Django signals / notification system

Is it a good aproach to use Django signals to implement email notification system? I have CustomUser model related with CustomUserPreferences planned as follows:
class CustomUserPreferences(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, default=None, on_delete = models.CASCADE, primary_key = True)
lesson_notification = models.BooleanField(default=True)
journal_notification = models.BooleanField(default=False)
login_notification = models.BooleanField(default=False)
excercise_notification = models.BooleanField(default=False)
homework_notification = models.BooleanField(default=True)
class CustomUser(AbstractUser):
...
email = models.EmailField(_('email address'), unique=True)
preferences = models.OneToOneField(CustomUserPreferences, null = True ,default=None, on_delete = models.CASCADE)
students = models.ManyToManyField(to = 'self', related_name = 'teachers', symmetrical = False, blank = True)
Whenever a new object of lets say Lesson is created I want to send an email to the user and that's fine - becaouse it won't overload any server.
The question is: will it pay off to use signals for a list of users that contains lets say 100s or 1000s of users? I'm afraid it will slow down the whole application.
Is there any other "clear and elegant" way to do this? Django docs advices not to use signals whenever it's possible.

How can I make a user out of a model in Django?

I'm currently developing a web-application for managing driving licenses as a web development homework assignment. Instead of just storing information on every driver as a model I want to make a user for each driver. What is the easiest way to do so? What am I doing wrong?
I updated a car owner model so that it is now inherited from djangdo Abstract User.
# models.py
class Car_owner(AbstractUser):
id_owner = models.IntegerField(primary_key=True)
last_name = models.CharField(max_length=30, null=False)
first_name = models.CharField(max_length=30, null=False)
birth_date = models.DateField(null=True)
passport = models.IntegerField(null=True, blank=True)
address = models.CharField(max_length=50, null=True, blank=True)
nationality = models.CharField(max_length=15, null=True, blank=True)
# username = models.CharField(max_length=16, unique=True, default=uuid4)
# password = models.CharField(max_length=16, default='password')
I also have forms.py file:
from django import forms
from project_first_app.models import Car_owner
class CreateOwner(forms.ModelForm):
class Meta:
model = Car_owner
fields = ['id_owner', 'last_name', 'first_name', 'birth_date', 'passport', 'address', 'nationality']
But when migrating I get the following issue:
UNIQUE constraint failed: new__project_first_app_car_owner.username
In migrations files I have:
migrations.AddField(
model_name='car_owner',
name='username',
field=models.CharField(default=uuid.uuid4, max_length=16, unique=True),
),
and then:
migrations.AlterField(
model_name='car_owner',
name='username',
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username'),
),
Those are automatically generated.
You have commented username and password in your model, why ?
Password field already exists in the abstractbaseuser, so comment it does not remove it. The abstract model user of Django need a unique information for authenticating user. You can use a Username or an Email.
For using the email instead of username, you can define USERNAME_FIELD = "email" in your class. But you have to define a field email, or you keep username field and add it to fields ModelForm.
There is a constraint on the username field (or email field), so you have to define it for each Car_owner you want to create (it is for authenticating purpose).
your field id_owner is useless, Django create automatically a field called id in each model which is the primary key.
so for resolving your problem easily, add username in fields list of your Form for beginning.

Export xlsx file with model having reverse foreign key relation and make that reverse foreign key relation as separate column

I am using django import_export package for export my data into xlsx file.
I am having issue while exporting the data to excel in the format I need.
models.py
class Fans(models.Model):
"""
Model for survey answering people
"""
fan_id = models.AutoField(db_column='FAN_ID', primary_key=True)
first_name = models.CharField(
db_column='FIRST_NAME', max_length=45, blank=True, null=True)
last_name = models.CharField(
db_column='LAST_NAME', max_length=45, blank=True, null=True)
phone = models.CharField(
db_column='PHONE', max_length=45, blank=True, null=True)
email = models.CharField(
db_column='EMAIL', max_length=45, blank=True, null=True)
gender = models.CharField(
db_column='GENDER', max_length=45, blank=True, null=True)
class Responses(models.Model):
"""
Model for responses given by fans
"""
survey = models.ForeignKey(
Surveys, on_delete=models.CASCADE, db_column='SURVEY_ID', related_query_name="part")
fan = models.ForeignKey(Fans, on_delete=models.CASCADE,
db_column='FAN_ID', related_query_name="given", related_name="given")
survey_question = models.ForeignKey(
SurveyQuestions, on_delete=models.DO_NOTHING, db_column='SURVEY_QUESTION_ID',
related_query_name="response")
response = models.CharField(
db_column='RESPONSE', max_length=255, blank=True, null=True)
correct_answer = models.IntegerField(
db_column='CORRECT_ANSWER', blank=True, null=True)
load_id = models.IntegerField(db_column='LOAD_ID', blank=True, null=True)
class SurveyQuestions(models.Model):
"""
Model for surveys questions
"""
survey = models.ForeignKey(Surveys, on_delete=models.CASCADE,
db_column='SURVEY_ID', related_query_name="question")
survey_question_id = models.AutoField(
db_column='SURVEY_QUESTION_ID', primary_key=True)
survey_question_name = models.CharField(
db_column='SURVEY_QUESTION_NAME', max_length=255)
question = models.CharField(
db_column='QUESTION', max_length=255, blank=True, null=True)
response_type = models.CharField(
db_column='RESPONSE_TYPE', max_length=255, blank=True, null=True)
load_date = models.DateField(db_column='LOAD_DATE', auto_now_add=True)
I want to export data of the fans with recorded responses in the following format:
first_name, last_name, phone, email, question1, question2, question3
abc, xyz, 1234566780, abc#gmail.com, response1, response2, response3
Here, the first four fields are directly from Fans model, however the last three column headers represent "question" field from SurveyQuestions model and values come from the "response" field of Responses model.
Till now, I am able to achieve the following format:
first_name, last_name, phone, email, given
abc, xyz, 1234566780, abc#gmail.com, {question1: response1, question2: response2, question3: response3}
given field is json of question-response as key-value pair.
admin.py
class FanResource(resources.ModelResource):
"""
Resource for exporting to excel
"""
given = fields.Field()
class Meta:
model = Fans
fields = ("first_name", "last_name", "email",
"phone", "given")
def dehydrate_given(self, instance):
res = {}
for x in instance.given.values('response', 'survey_question__question'):
res[x['survey_question__question']] = x['response']
return json.dumps(res)
Any help would be appreciated. Thanks in advance!!
14/10/20 UPDATE
Using the answer below, I was able to achieve the format required. Code is as follows:
def after_export(self, queryset, data, *args, **kwargs):
survey_questions = {x["survey_question_id"]: x["question"] for x in SurveyQuestions.objects.filter(
survey=self.survey).values('survey_question_id', 'question')}
for k, v in survey_questions.items():
res = []
for x in queryset:
try:
res.append(x.given.get(survey_question=k).response)
except ObjectDoesNotExist:
res.append(None)
data.append_col(res, header=v)
Now, the issue is that it is taking too long as it is hitting the database for each entry. And other issue is order is not proper (i.e responses are not in same line as per the corresponding fans).
I think the way to achieve this would be to override after_export(), and manipulate the exported dataset. For example:
def after_export(self, queryset, data, *args, **kwargs):
response1 = [i for i in range(data.height)]
data.append_col(response1, header="response1")
response2 = [i for i in range(data.height)]
data.append_col(response2, header="response2")
This will append new columns to the end of the export. In after_export() you will have access to both the data set and the queryset, so hopefully you can manipulate this data to fill the 'response' columns correctly.

django rest framework how to save mutiple phone number and email?

In Django framework, I have a model like this:
class Employee(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE,related_name='organization_user')
added_by = models.ForeignKey(Hr, on_delete=models.CASCADE, related_name='added_user')
email = models.CharField(max_length=30, null=True, blank=True)
phone = models.CharField(max_length=30, null=True, blank=True)
The Employee is not a Django auth user, and I need to save the employee with multiple emails and phone numbers.
I am using the SQLite database it's not having ArrayField as a model option.
Already tried like this :
phon1='9400' (already in db)
phon2='9411' (input number)
phon = phon1 +','+phon2
'9400,9411'
But here is the chance to create duplicate phone numbers.
Then how can I save the employee with multiple fields?
While technically you can have your phone numbers (and emails) as "num1,num2,..." and prevent duplicates, it's not generally a good idea to store them in this way.
The best-practice is something like this:
class Employee(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE,related_name='organization_user')
added_by = models.ForeignKey(Hr, on_delete=models.CASCADE, related_name='added_user')
class PhoneNumber(models.Model):
number = models.CharField(max_length=30)
employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
class Email(models.Model):
email = models.EmailField(max_length=30)
employee = models.ForeignKey(Employee, on_delete=models.CASCADE)

Django: Converting a GenericForeignKey Relationship to a ForeignKey Relationship

I'm working to remove an existing GenericForeignKey relationship from some models. Id like to change it to the Reformatted Model below. Does migrations provide a way to convert the existing content_type and object_ids to the respective new ForeignKey's? (to keep existing data). Basically brand new at programming, so pardon me if I'm asking a stupid question.
class Donation(models.Model):
amount_id = models.CharField(max_length=12, unique=True, editable=False)
date_issued=models.DateField(auto_now_add=True)
description=models.TextField(blank=True, null=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type','object_id')
class Individual(BaseModel):
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50, blank=True,
null=True)
last_name = models.CharField(max_length=50)
suffix = models.CharField(max_length=50, blank=True, null=True)
contributor = generic.GenericRelation(Donation, related_query_name='individual')
class Organization(models.Model):
name = models.CharField(max_length=100)
contributor = generic.GenericRelation(Donation, related_query_name='organization')
Reformatted Model
class Donation(models.Model):
amount_id = models.CharField(max_length=12, unique=True, editable=False)
date_issued=models.DateField(auto_now_add=True)
description=models.TextField(blank=True, null=True)
contributor_group = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE)
contributor_individual = models.ForeignKey(Individual, null=True, blank=True, on_delete=models
Based on your model definition of Donation Model, one of fields contributor_group , contributor_model will always be Null post migration.
I hope you have taken that into you consideration.
Just to be safe Do this in two phases.
1. Keep the content_type and object_id and add the two new fields.
2. Next step remove the generic fields post data population.
There are two ways to populate those new fields
Django migrations provides you a way to populate new fields with values during the migrations. You can look it up. I haven't done that before either.
For more control and some learning as well. You can populate that via scripting as well. You can setup django-extensions module in your project. And write a script to do that population for you as well. A sample script would look like.
from myproject.models import Donation, Individual, Organization
from django.contrib.contenttypes.models import ContentType
def run():
organization_content_type = ContentType.objects.get_for_model(Organization)
individual_content_type = ContentType.obejcts.get_for_model(Individual)
donations = Donation.objects.all()
for donation in donations:
if donation.content_type_id == organization_content_type.id:
donation.contributor_group = donation.object_id
elif donation.content_type_id == individual_content_type.id:
donation.contributor_individual = donation.object_id
else:
print "Can't identify content type for donation id {}".format(donation.id)
donation.save()
Check the values are correct and then remove the generic fields.
Facing some issues with formatting here.