Updating user information from separate model Django - python

I'm creating a simple weight management application where users can register, login and update information such as weight, body measurements etc. I've not used Django for a little while and slowly learning best practices from where i left off a little while ago.
I'm using the django-allauth to manage the user registration as this allows people to login with Facebook etc.
I've created a simple app called 'Stats' with a ForignKey to the Users.
class Stat(models.Model):
user = models.ForeignKey(User, default=False)
height = models.CharField(max_length=20)
weight = models.CharField(max_length=20)
waist = models.CharField(max_length=20)
hips = models.CharField(max_length=20)
upperleg = models.CharField(max_length=20)
upperleg = models.CharField(max_length=20)
calf = models.CharField(max_length=20)
bodyfat = models.CharField(max_length=20)
What i would like the user to be able to do is login and update stats on a daily / weekly basis. Then to be able review previous stats. This will probably be done via a model form based on the above approach. I will add more complexity as time goes on.
Is there another way to do that would have any advantages? If the best approach is the best? Is there a way i can list all the objects from that model inside the users page in the admin to be able to reviews users stats easily enough?
Thanks in advance.

It is recommended that you create a separate user profile model for app-specific functionality that relates to a User of your app. It's best to create a UserProfile model which has a OneToOneField link to User object. Then, your Stat model can ForeignKey to UserProfile instead of User. This is to provide abstraction to the User object and give flexibility if you decide to create another Django app in the same project that requires different specifications for the user. Also, with UserProfile you can add customised fields that are app specific.
Another thing you can do to improve this modelling is create separate entities for each stat. For example, HeightWeightStat, WaistStat. But, this is not completely necessary and totally depends on your preference.
To display all of the user related Stat instances in the admin page, use Django Admin inlines: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#inlinemodeladmin-objects

Related

Foreign key model in Django Admin

I have two user roles in Django:
Commercials
Sellers
I have created two models, Seller Model has a ForeignKey field to Commercials (every seller has a commercial related to). When I register the models in admin I can create Commercials and related sellers using StackedInline, TabularInline etc.
The problem I have is I need to associate users to this models in order to authenticate, login, etc. In admin I need to create a user (in an inline way, not dropdown box)
This is my code:
In models.py:
class Commercial(models.Model):
name = models.CharField(max_length=255, null=True)
user = models.OneToOneField(User, null=True)
class Seller(models.Model):
name = models.CharField(max_length=255, null=True)
commercial = models.ForeignKey('Commercial')
user = models.OneToOneField(User, null=True)
In admin.py:
class SellerAdmin(admin.StackedInline):
model = Seller
extra = 1
class CommercialAdmin(admin.ModelAdmin):
inlines = [SellerAdmin]
admin.site.register(Commercial, CommercialAdmin)
I need to edit, create, users etc. related to this models inline not in a modal window, Is there any way?
There is no way to make a reverse relation (so to say) in the form of Inlines. The Django admin panel doesn't have that ability by default.
What you could do is unregister the default UserAdmin, create a new Admin panel by inheriting the original one, and add this Seller as an Inline. There is still the issue that Django doesn't support multiple inlines, hence, you will not be able to use the Commercial model in the same admin page.
To fix that, you could refer to this information from the doc which shows how to overwrite the automatically created ModelForm for a particular ModelAdmin.
This will however not be that helpful as they are a lot of work. I would rather suggest implementing a workaround in how your application is used, rather than complicating it this much. Depends on the needs of the project, whether you need to go through this much trouble
Django nested inlines library might help you.

Django: Including standard User table as foreign key in my models?

I am designing a Django 1.8 application in which I have the concept of trials and assessors. I will have six assessors, who will use the Django admin to log in and make assessments.
I want each trial to have two attached assessors. How can I use the Django User model in models.py to ensure that the assessors are Users, and can be managed using the full power of Users?
Right now I have this, in which the assessors are not Users, but are just ordinary models:
class Assessor(models.Model):
name = models.CharField(max_length=200)
class Trial(models.Model):
title = models.CharField(max_length=800)
publication_date = models.DateField()
first_assessor = models.ForeignKey(assessor)
second_assessor = models.ForeignKey(assessor)
I want the assessors to be Users, so that I can manage them in the usual way through the User tables, but I don't know how to make this change.
They probably don't need any custom fields on top of the standard User attributes.
(NB: I don't need full-on permissions management within the admin, it's OK for any assessor to be able to edit the trial.)
UPDATE: Apologies, this is rather hard to explain! I don't care about the Django front-end at all, only the admin. I want a user to be able to log into the admin, see all the trials on which they are a primary assessor, and edit those trials. I'm not sure if it's best to do this with the User model, or not.
Instead of two foreign keys add a manytomany relation from Trail to user. Later, if you want you can add more assessors to a trail.
You can do like:
from django.contrib.auth.models import User
class Trial(models.Model):
title = models.CharField(max_length=800)
publication_date = models.DateField()
assessors = models.ManyToManyField(User,related_name="trials")
You can add assessors to Trial like:
trial = Trial.objects.get(id=give-trial-id)
user = User.objects.get(id=give-assessor-id)
trail.assessors.add(user)
You can get more info about manytomany here
I just saw your UPDATE. Any one who logs in to admin will have access to all objects of all models.
In your case all assessors who login to admin will have access to all trails irrespective of they are assigned to it or not.
If you want Filter django admin by logged in user then refer this question

Django custom user models in 1.8

I'd like to create a project for finding mentor.
In planning i thought, that it would be nice to separate two models on registration users: for students (those, who wants to find mentor) and mentors.
Built-in django user model isn't like that. I plan to add more fields, also several fields can be the same: in students and in mentors.
Can you give me live example of customing model? Would be nice, if you have smth in git or other code sharing.
Shoudl I inherit mentor model from students, because it can have same fields: email, name, surname, etc?
What additional code should i write for working custom model? I read docs and found unknown for me - managers. Should i also customize managers?
If i get success in custom model what problems can i meet in future for auth,registration, changing passwords for this custom model?
Creating 2 separate models is not recommended here. You will need to have separate login process and be careful to avoid problems with sharing pk between users in separate tables. Also I'm pretty sure that django won't allow that.
Better choice is to make 2 profile models, as described in Extending the existing User model. In one of profiles you will store specific data for student and in other specific data for mentors.
Your website has two intended users, so there is no problem with creating two user models. Just make sure to inherit them from user model
from django.contrib.auth.models import User
class Student(User):
...
class Mentor(User):
...
You shouldn't re-invent the wheel, except you really want to learn and practice core features of Django. Just add some add-on library like userena, which "supplies you with signup, signin, account editing, privacy settings and private messaging". In general userena gives an additional UserenaBaseProfile model which is connected to built-in User model. So you can just inherit this model for the Student and for the Mentor:
from django.contrib.auth.models import User
from userena.models import UserenaBaseProfile
class CustomProfile(UserenaBaseProfile):
user = models.OneToOneField(User, unique=True)
common_field_for_all_children = models.IntegerField()
class Meta:
abstract = True
class Student(CustomProfile):
something_student_related = models.IntegerField()
class Mentor(CustomProfile):
something_mentor_related = models.CharField(max_length=255)

django best approach for creating multiple type users

I want to create multiple users in django. I want to know which method will be the best..
class Teachers(models.Model):
user = models.ForeignKey(User)
is_teacher = models.BooleanField(default=True)
.......
or should I use..
class Teacher(User):
is_teacher = models.BooleanField(default=True)
.......
or I have to make custom user model...
Which will be good on creating multiple type users...??
Django doesn't have multiple users - it only has one user and then based on permissions users can do different things.
So, to start off with - there is only one user type in django. If you use the default authentication framework, the model for this user is called User, from django.contrib.auth.models.
If you want to customize user behavior in django, there are three things you can do:
Customize how you authenticate them. By default, authentication is done using a database where passwords are stored. You can authenticate against facebook/google etc. or against your existing user database - for example, with ActiveDirectory if you are on a Windows network.
Create custom permissions, and based on these permissions, restrict what functions users can execute. By default, on every model - django will add basic permissions "can edit", "can delete", "can read". You can create your own and then check if the user has these specific permissions.
You can store extra information about the user, along with whatever normally is stored by django. There are two ways to do this, depending on how much customization you need. If everything django provides by default works for you, and all you want to do is store extra information about the user you can extend the user model - in previous versions this was called creating a custom profile. The other option you have is to create your own User model, if you want deeper customization. The most common use of a custom user model is if you want to use an email address as the username.
You don't have to do all three, in fact sometimes all you want to do is store some extra information or have them authenticate using their email address; in some applications you have to modify all three places.
In your case, since all you want to do is store extra information about a user, you would need to extend the user model, by creating a model that references User (note: you don't inherit from User):
class Profile(models.Model):
user = models.OneToOneField(User)
department = models.CharField(max_length=200, default='Computer Science')
is_teacher = models.BooleanField(default=False)
is_student = models.BooleanField(default=True)
# .. etc. etc.
One approach I was following with Django 1.7 (works with 1.6 too) is to subclass AbstractUser
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
balance = models.DecimalField(default=0.0, decimal_places=2, max_digits=5)
To use your model you need to set it to be the one used for authentication in settings.py:
AUTH_USER_MODEL = 'your_app.User'
Also note that you will now have to use settings.AUTH_USER_MODEL when referencing
your new User model in a relation in your models.
from django.db import models
from django.conf import settings
class Transaction(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL) # ForeignKey(User) will not work

Django: Accessing user profile data in another app

I am currently working on a django application and I am trying to develop a little recommendation system for it. I already extended the User model and made a user profile in an app called profile like so:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
skills = models.CharField(max_length=150)
skillsNeeded = models.CharField(max_length=150)
bio = models.CharField(max_length=300)
industry = models.CharField(max_length=70)
occupation = models.CharField(max_length=70)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
However now I made a separate app within the same Django project called matches and I was wondering how I could pull the current user's data from their profile as well as getting a list of every other user that is in the database. I am using postgresql as my database management system, any ideas or help would be much appreciated. I would think I would need to find out where the profile data is stored in the database and make manual sql queries. However, I am still relatively new to django and this is my first time using postgre for dbms instead of mysql.
Manual SQL queries are almost never necessary. It sounds to me like you just need to use the data models in their basic form to do queries. For example, the current user is available in your views as request.user, so you could get their profile like so:
UserProfile.objects.get(user = request.user)
And getting all of the users is as easy as:
User.objects.all()
I think there is a slight confusion here. Apps in Django are just a heavy-sounding name for a module. Usually, all of your different "apps" will share the same database and can and should import other apps' models to get their work done.

Categories

Resources