Creating a new instance of a Custom User Model in Django - python

I have a model which is an extension of a User model in Django 1.8. I am also connecting to a MySQL database for this.
class LibraryUser(models.Model):
user_id = models.OneToOneField(User)
is_catalogue_subscriber = models.BooleanField(default=True)
is_research_subscriber = models.BooleanField(default=True)
library_membership_number = models.CharField(max_length=64)
The reason why I extended the User model, of course is to use the authentication framework.
So now, I want to create a new LibraryUser using the library_membership_number as the login username. How should I do so? Do I create the User first then reference the LibraryUser?
ie given some_ variables either received by a POST or by migration of users to the new table
u = User.objects.create_user(email=some_email, password=some_password)
lu = LibraryUser(library_membership_number, user_id = u.id)
lu.save()
Or is there a correct way to do this? Tried finding online but can't find something to particularly address this problem.

You should assign value to the specify fields as the following:
lu = LibraryUser(library_membership_number= '...', user_id = user)
lu.save()
library_membership_number
You can't just assign a variable to library_membership_number. model is a object containing the fields. You should appoint the field and assign it: library_membership_number= '...', or model can't parse which field you will store.
user_id
It has defined foreignkey in advance. It can accept another model object to store: user_id = user. Don't call attribute of the user to store in LibraryUser.

Related

how to get a column value of foreign key in the form of object?

There is 2 models Registration and RegistrationCompletedByUser, I want Registration queryset from RegistrationCompletedByUser with filters(user=request.user, registration__in=some_value, is_completed=True) over RegistrationCompletedByUser. Hence result should be like <QuerySet [<Registration: No name>, <Registration: p2>, <Registration: p-1>]>.
Now what I tried is
Registration.objects.prefetch_related('registrationcompletedbyuser_set') but filters() not working. Another way I tried is model Managers but don't pass parameters for custom filtering.
models.py
class Registration(models.Model):
name=models.CharField(max_length=255)
number=models.SmallIntegerField(null=True, blank=True)
class RegistrationCompletedByUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
registration= models.ForeignKey(Registration, on_delete=models.CASCADE)
points = models.SmallIntegerField(default=100)
is_completed = models.BooleanField(default=False)
If I understood this properly, you want to get all Registrations that related to a query instead of a single object.
qs_1 = RegistrationCompletedByUser.objects.filter(user=request.user, is_completed=True).values_list("registration__id", flat=True)
qs_2 = Registration.objects.filter(id__in=qs_1)
As I understood your question is related to django. So actually there is common way to get related query set from another. When you specify ForeignKey to another model actually django automatically creates 'Related Model' + '_set' relation.
I actually didn't get from you question what you are intended to do. In your situation there are many RegistrationCompletedByUser related to one Registration. So what you can do it's to receive all RegistrationCompletedByUser instances from Registration instance by related name for ForeignKey registration of RegistrationCompletedByUser which in your case registration_set. Actually better to specify in RegistrationCompletedByUser model related name as attribute like this:
models.ForeignKey(Registration, on_delete=models.CASCADE,
related_name='registrations')
And after this let's say you have instance of Registration reg1. So to receive queryset of RegistrationCompletedByUser:
reg1.registrations.all()
And you can use filter on it with attributes from Registration model.
And if you want to receive Registration from RegistrationCompletedByUser, again in your case it's just one Registration to many RegistrationCompletedByUser, so let's say we have reg_completed_1, to receive it's only one registration:
reg = reg_completed_1.registration

It is impossible to add a non-nullable field Error when extending Abstract User

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.

Why is Django's `add()` method in my `many-to-many` Django models not taking?

Question / Problem:
I am building a Django app, with 2 models: User and Secret. Secrets can be made by Users, and other Users can "like" them. I've setup my likes field as a ManyToManyField, so that Users whom like a Secret can be stored there and later retrieved, etc. However, when I try to query for a User and a Secret and use my_secret.likes.add(my_User) nothing happens. I don't receive an error and when I print my Secret's many-to-many likes field, after the add, I see: secrets.User.None.
Why is my add() method running but I am not receiving any errors, and why is my User not properly being added to my Secret's likes?
Note: I've saved both the User and Secret objects upon initial creation. Outside this application I've been able to use the add() method just fine, but in those scenarios I was creating objects in the moment, and not retreiving already existing objects.
Is there a different way to handle add() when using data retreived from a Query? That's my only other line of reasoning right now, and I've followed the documentation here exactly: Django Many-to-Many Docs
I also apologize if this was answered elsewhere on the site. I did find one other post here, but there was no solution provided, granted they were experiencing the exact same issue.
My Models:
class User(models.Model):
"""
Creates instances of a `User`.
Parameters:
-`models.Model` - Django's `models.Model` method allows us to create new models.
"""
first_name = models.CharField(max_length=50) # CharField is field type for characters
last_name = models.CharField(max_length=50)
email = models.CharField(max_length=50)
password = models.CharField(max_length=22)
created_at = models.DateTimeField(auto_now_add=True) # DateTimeField is field type for date and time
updated_at = models.DateTimeField(auto_now=True) # note the `auto_now=True` parameter
objects = UserManager() # Attaches `UserManager` methods to our `User.objects` object.
class Secret(models.Model):
"""
Creates instances of a `Secret`.
Parameters:
-`models.Model` - Django's `models.Model` method allows us to create new models.
"""
description = models.CharField(max_length=100) # CharField is field type for characters
user = models.ForeignKey(User, related_name="secrets") # One-to-Many Relationship
likes = models.ManyToManyField(User) # Many to Many Relationship
created_at = models.DateTimeField(auto_now_add=True) # DateTimeField is field type for date and time
updated_at = models.DateTimeField(auto_now=True) # note the `auto_now=True` parameter
objects = SecretManager() # Attaches `SecretManager` methods to our `Secret.objects` object.
Problem Example:
The model migrates fine, everything seems to be in proper syntax. However, when I try and retrieve a User and a Secret, and add the User to the Secret.likes, the add() method gives no errors, runs, but no objects are saved.
Here's an example:
tim = User.objects.get(email="tim#tim.com") # Gets a user object
my_secret = Secret.objects.get(id=2) # Gets a secret object
# This is where nothing seems to happen / take:
my_secret.likes.add(tim) # add() method per Django many-to-many docs
print my_secret.likes # returns: `secrets.User.None` -- why?
Why when printing my_secret.likes above, is nothing printed?
Especially when:
tim.secret_set.all() shows the secret containing an id=2 as in the above example....so the User is recording the relationship with the Secret, but the Secret is not recording any relationship with the User. What am I doing wrong?
You need to call the all method of the many-to-many field to view all related objects:
print my_secret.likes.all()
# ^^^^^

Filter user in django and add to a existing group

I am new to Django and I have failing on a task now for a while. I have searched in the Django docs and here for some questions but there nothing is working for me.
Here is my view:
def user_accept(request):
if request.method == 'POST':
username = AddUser.objects.filter(owner=request.user).get().user_request
group_name = Projects.objects.filter(user=request.user).get().group_url
group = Group.objects.get(name=group_name)
group.user_set.add(username)
delete_user = AddUser.objects.filter(user_request=username)
delete_user.delete()
Here is my model:
class AddUser(models.Model):
owner = models.ForeignKey(User)
title = models.CharField(max_length=20, default='', blank=True)
user_request = models.CharField(max_length=30, default='')
answer = models.BooleanField(default=False)
AddUser model is used for users to request access to a specific project. So when a user is requesting a project, data is saved to the AddUser model.
The user field is set to the "owner" of the project so I can filter every project with a proper owner.
If the owner decides to accept the request my user_accept view is executed. Here is the problem, when I try to add the username into the group, I get the following error:
invalid literal for int() with base 10: 'myusername'
I have tried to convert the username with int(username) and tried to get the username's user_id but nothing seems to work... I think it have something to do how I filter my objects but I don't get it.
So thanks a lot for your time, and have a happy new year!
You need the user id or the user object itself to add a user with group.user_set.add.
You can either retrieve the user object from the username, provided usernames are unique and add that:
user = User.objects.get(username=user_request)
group.user_set.add(user)
Or change your AddUser model to store the requester's id via a OneToOne field or ForeignKey instead of username.
Django default groups doesn't allow you to add username into it.
You have to add User objects.
Try
add_user_object = AddUser.objects.filter(owner=request.user).get()
group.user_set.add(add_user_object.owner)

Django Rest Framework not saving foreign key for a small number of requests

I am using Django Rest Framework to provide API to a mobile app. I have two models, Order and User. Order has a foreign key relation to User.
For about 1% or so of all my order objects, the User field is null. I've been testing this behavior using cURL.
If I do a cURL without a user object, it tells me "This field is required".
If done with a wrong user object, it tells me that the object does not exist. Both of these are the intended and expected behaviors.
I'm trying to figure out how it is possible for some of the Order objects to be saved without a user field. Is there something I'm not taking into account?
My views:
class OrderList (generics.ListCreateAPIView):
model = Order
serializer_class = OrderSerializer
And serializer:
class OrderSerializer (serializers.ModelSerializer):
user = serializers.SlugRelatedField(slug_field = 'user')
partial = True
class Meta:
model = Order
Models:
class User (models.Model):
uid = models.CharField(max_length =200, unique=True)
class Order (models.Model):
uid = models.ForeignKey (User, related_name = "orders", verbose_name = "User",blank=True, null=True)
You could use two different ModelSerializer classes, one for creation, that makes sure, that an Order object can't be created without a related User and one for updating orders, that passes required=False to the related field's constructor, so that you still can save existing orders that haven't a related User.
Try adding default=None to your models.ForeignKey declaration. You could also just create an anonymous user in the users table and when the user isn't specified it could set the anonymous user instead.

Categories