Creating users in the database - python

Im modeling database tables for register/login pages. At the first insert all ends without any errors, but following insert return IntegrityError exception:
duplicate key value violates unique constraint
"mainws_user_role_id_key" DETAIL: Key (role_id)=(1) already exists.
If OneToOneField making rows only as unique, it means, that I cant create many users with one role, right? Then better using ForeignKey(Role) for this situation, or not?
Source code:
class User(models.Model):
login = models.CharField(max_length=50)
password = models.CharField(max_length=50)
address = models.CharField(max_length=255)
phone = models.CharField(max_length=25)
postcode = models.CharField(max_length=25)
email = models.EmailField()
role = models.OneToOneField(Role, primary_key=False)
class Role(models.Model):
role_name = models.CharField(max_length=25, unique=True)
def create_user(user_data):
md5 = hashlib.md5()
md5.update(user_data['password'])
user_role = Role.objects.filter(role_name='user')[0]
password_md5 = md5.hexdigest()
new_user = User(login=user_data['login'],password=password_md5,address=user_data['address'],
phone=user_data['phone'],postcode=user_data['postcode'],
email=user_data['email'],role=user_role)
new_user.save()

I would think your issue is in the OneToOneField. As its name implies, you can only associate one role with one user. A foreign key represents a ManyToOne relationship, that is what you want in this case, many users can have one role.
On the other hand, you are trying to create users on your own when Django already has most of that by default. Frameworks are there to avoid you making sensitive parts of your application manually.
You may want to check documentation if you don't know how to do that.

Related

how to output data from a linked table in django?

I have a built-in User table and a Note table associated with it by key.
class Note(models.Model):
header = models.CharField(max_length=100)
note_text = models.TextField()
data = models.DateField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
That is, a registered user may have several notes. How do I get all these notes from this particular user (who has now visited his page)? I need to get these notes in views.py.
I tried different ways, don't know how to do that.
Hope this answer finds you well ...
First, you already have a user object in your request. But, still you want to filter out notes for other users too, then do
get_user = User.objects.get(id=id) # For any random user
get_user = request.user # For authenticated user
After getting the user, you simply filter it with the Note model like this ...
get_notes = Note.objects.filter(user=get_user)
You are good to go!

Delete 2 model different objects which reference each other as foreign keys

We have two Django models:
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
usernmae = models.CharField(max_length=50)
active_project = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
I have a user with object (with id say 692). And this user created a project with id=12345, therefore these owner field will get have this particular referenced.
I want to delete that user. But it shows error that
delete on table "app_user" violates foreign key constraint
This is expected as on_delete=models.DO_NOTHING, was set. One way I found out was using on_delete=models.CASCADE.
Question: How should I go about deleting the user (692) without changing the model definition(having to re-run migration)?
Doing it manually by deleting the project first, leads to the same foreign-key error, as owner field is User object.
How to handle this mutual foreign key relationship while deleting, as deleting any one of those two throws the foreign-key exception?
Update
Some correction in the model definition username is the field name instead of usernmae (typo). And the foreignkey for project is Project not the User model.
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
username = models.CharField(max_length=50)
active_project = models.ForeignKey(Project, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
IF you really don't want to make a migration (any specific reason?) and if you are ok with doing this manually this time. Then you have two options:
Go into the admin panel and manually change the User field in the project instance to a different user or to NULL. Now you should be able to delete the User instance since it's not referred anymore into the project.
If that worked, you can then delete the project instane as well.
Curios if this will work, let me know!

How to define django's many to many field in postgres?

I have a django model called Contexts which is essentially a group that has a list of users.I have another model called UserProperty which has some user information.
class Contexts(models.Model):
context_name = models.CharField(max_length=50)
context_description = models.TextField()
users = models.ManyToManyField(UserProperty , related_name='context_users')
def getUserImagePath(instance,filename):
return "/static/images/%s_%s"% (str(time()).replace('.','_'),filename)
class UserProperty(models.Model):
username = models.CharField(max_length=255, null=False)
pic = models.ImageField(upload_to=getUserImagePath, default="/static/images/user.png" ,null=True, blank=True)
org = models.CharField(max_length=255, null=True)
This works fine in my local system when I run a migration using django manage.py.But in the server for some reason, I cannot run migrations and I have to define the models manually in postgres (the server uses django _ postgres).So this is what I did
CREATE TABLE webhook_contexts(id integer, context_name character varying(100), context_description character varying(100), users text [], FOREIGN KEY (users) REFERENCES webhook_userproperty);
I am not sure exactly how to replicate this in postgres.For users field in Contexts model, I did models.ManyToManyField(UserProperty , related_name='context_users') so I assume the users must be an array in postgres that contains the fields of the referenced table UserProperty namely username, pic, org.So I do
.., users text [], FOREIGN KEY (users) REFERENCES webhook_userproperty)
But I get this error
ERROR: there is no primary key for referenced table "webhook_userproperty"
But I did define an id for the webhook_userproperty which django treats as a primary key.Then why am I getting this error?Is my table definition wrong?

Selecting foreign keys in Django REST Framework's Browsable API

I have a simple ForeignKey relationship between two models:
class Ticket(models.Model):
description = models.CharField(max_length=1000)
created_by = models.ForeignKey(User, related_name="created_ticket")
class User(models.Model):
username = models.CharField(max_length=64, unique=True, primary_key=True)
email = models.CharField(max_length=255)
I have a serialiser for each, with the user serialized within the ticket as a nested serialiser. What I would ideally like is
in an update view of Tickets on the Browsable API, being able to choose from a dropdown list of extant users, and
when entering a username and an e-mail, the application should check if users exist with those parameters, and if so, assign them to the ticket, and if not, raise a validation error (the validation part I got working, the rest... not so much).
So far, I've tried to follow overriding the update/create methods, but when I enter a code, the application always tries to create a new object, then complains that an object with the same username (the pkey) already exists. I have tried getting some sense out of the documentation on the subject, but with not much luck.
EDIT: My update method is
def update(self, instance, validated_data):
usr_data = validated_data.pop('created_by')
instance.created_by_id = usr_data.id
return instance

Schema - Ability to change email address (primary user id) in Django

Currently my user table looks like this - (all fields are not null)
display_name = CharField # string
email_address = EmailField (primary key) # string
password = CharField # string
However, I have decided to add additional functionality and to allow users to change their email addresses.
The flow goes like this
Does anyone have any ideas on how to do this?
Currently I am thinking of something like
display_name = CharField # string
email_address = EmailField (primary key) # string
password = CharField # string
pending_email = EmailField (unique) # string
And simply hold the new email address in pending_email before replacing the old email address in email_address
But obviously this is far from perfect (e.g. pending_email unique constraint does not cover email_address)
Ive thought about just leaving it like this and performing more selects against the database with AJAX queries to check if the desired new email address already lives in email_address before allowing it to be entered into pending_email but this seems still vulnerable to race conditions and poor user experiences on top of being not very database friendly.
The standard practice in this sort of situation is to create a separate table for email addresses. That allows users to have more than one email address at a given time and one of them can be marked as default.
This is what django-allauth's EmailAddress model looks like. In fact, unless you have a very compelling reason to write your own authentication system, I highly recommend that your swith to django allauth or any of the widely used django authentication/registration system.
class EmailAddress(models.Model):
user = models.ForeignKey(allauth_app_settings.USER_MODEL,
verbose_name=_('user'))
email = models.EmailField(unique=app_settings.UNIQUE_EMAIL,
max_length=app_settings.EMAIL_MAX_LENGTH,
verbose_name=_('e-mail address'))
verified = models.BooleanField(verbose_name=_('verified'), default=False)
primary = models.BooleanField(verbose_name=_('primary'), default=False)
objects = EmailAddressManager()

Categories