I using One To One field in Django to save some extra information about user but even afte migrating i got the issue which i mentioned in title
my models.py
the issue I got
issue while running server
please help if you can
The error you are getting:
User has no profile
Simply means what it says, meaning the particular User instance you are dealing with has no related Profile. Now you might be wondering why not, but that is because a User record can perfectly exist without a 'Profile' relation, the constraint only applies to your profiles, which cannot be created without a corresponding user record.
So if you have somehow tried linking the user to a certain profile, that means the code that is supposed to make that happen isn't doing so and from what I got from the images, you're using signals for that. But I wouldn't recommend doing so, not because signals are generally bad, but because in this case its sorta overkill, and it spreads your code too much.
What I'd suggest/recommend is to add the logic to create profile in the User creation form.
Your problem is probably because the user does not have an associated profile in the DB.
Even though there is an OneToOne relation there doesn't a guarantee. that a user will have a profile.
So you probably need to create a profile for that user.
Also if you want to extend the user model, Ill recommend that you check out this. It contains more ways to achieve what you are looking for
profile doesnt get created automatically ,you need either to add it manually or use signals so that every time a user is created a profile also is created,
if you have a profile model lets say you named it Profile
create a signals.py and add this to it:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, *args, **kwargs):
if created:
Profile.objects.create(user=instance)
If you're adding blank=True, then why are you adding default=''
If you want profile picture to be mandatory, remove blank=True
Related
I took over a django web app and am still relatively new to django. I want to trigger a function whenever a new user registers on the website. But there is no code in the project to process the user registration. It all seems to happen under the hood. So I don't know where could put such a function call. The web app uses django.contrib.auth.
Additionally: How can I trigger a function when an account is activated?
You can use the signals to trigger an event when you save anything in your db, include the User from auth. You can see the django doc about this.
In your case, I think that the best way is like:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import user
#receiver(post_save, sender=User)
def user_saved(sender, instance, **kwargs):
...
In the kwargs you can see, for example, if object is created or modified. The sender is the Class and the instance is the object.
I just started a Django project (there are no apps in it). I activated the admin in settings file and can access the Django administration page. There is a column in Django page to add users; while adding users I get only three fields under personnal info, but I need to store some more information about users. I Googled around and found that I can use user profiles to accomplish this. I tried, but I am having problems.
My aim is to add three more fields to the user table:
role
contact number
other
I need details like: which function I need to write and where to do this.
I found this, but I do not know where I need to write these steps. I would greatly appreciate a more clear explanation of this.
Django User Profiles is what you need. The blog you linked to has clear steps on how to do it. You can check out the Django documentation. http://www.turnkeylinux.org/blog/django-profile also provides a good explanation.
Basically you need to create a new model with User as ForeignKey and define the model in the settings.py as AUTH_PROFILE_MODULE = "django_app.your_profile_modelname". Create the profile and save it just like any other model, and access it using user.get_profile()
Adding a couple of things in response to your questions below:
First, do not create apps as a directory. Use startapp <appname> [destination] as described here. That will create the app directory.
Second, you have to add the app to INSTALLED_APPS in the project's settings file, do a syncdb. Basically, follow the steps in Django tutorial on writing your first app.
Third, UserProfile is a separate model. It is not an extension of User. It is associated with the User just because you added User as the ForeignKey.
Fourth, to be able to see the user profile model in admin, you do exactly what you would do to add any other model to admin page. Create a file names admin.py under your app with:
from django.contrib import admin
from myproject.app.models import UserProfile
admin.site.register(UserProfile)
There are three key concepts to understand:
There is no built in "profile" system in Django, beyond the limited auth app which is really geared just to user login. You are expected to roll your own.
There is nothing magical about a profile record in itslef, it is just like any other record that takes User as a foreign key (or, more properly, a one-to-one field as per the docs). You create it by creating a custom django app (traditionally called profiles) and a model for that app (traditionally called UserProfile, since Profile is not allowed as a model name).
The only thing that sets UserProfile aparts as a model is that you specify it as the AUTH_PROFILE_MODULE which means that it is accessible when called .get_profile() on a User record. That's it. If you set up the UserProfile like so:
def UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
other fields
then you can also access the profile as user.profile rather than user.get_profile() which some people prefer.
Again, nothing magical about the profile model -- it is just a model record like any other model record.
If you want to be able to edit additional fields within the user form that's more complicated; easiest way is probable unregister User and then register it again using your custom ModelAdmin and form class but judging by your question you're probably not at that level yet.
My old worker installed Pinax through PIP and it's installed in site-packages. All the apps lives there. Our own apps are within our Django project structure.
I want to modify Pinax's account app, by switching the create_user's is_active flag to False. Currently, the app makes it True. I also want to add additional functionality to create_user or whatever function I want to do.
from pinax.account import forms
class MyCustomizeForm(forms.SignupForm):
def create_user(....):
super(....)
// additional...
Maybe this?
But doesn't that require me to do at least two commit transactions talking to DB?
Is that preferable? Also, does doing this require me to change anything else in my Django project (how users signup, what views it uses... what forms it uses)?
Currently, I've an app living in my Django project supposes to deal with the extension / customization of account app. I can't commit site-packages to VCS.... I mean.. I am not supposed to make any changes there.
Thanks.
Pinax account/models.py
class Account(models.Model):
...
def its_own_method(...)
# this is in the same indentation level as class Account
def create_account(sender, instance=None, **kwargs):
if instance is None:
return
account, created = Account.objects.get_or_create(user=instance)
post_save.connect(create_account, sender=User)
You can use the django signals for exactly this situation. Signals are meant for apps that need to be distributed generally and won't always know how they will be integrated into a project.
The signal of interest to you here is the pre_save. You can connect a pre_save to the pinax.account model and be notified when a save is about to happen. This will give you a chance to make changes to that model instance. Signals are synchronous, meaning you are making your change serially, right before the pinax.accounts will finish committing the save
I'd like to switch databases upon user login. I've created this login signal.. but it doesn't work
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.db import connections
#receiver(user_logged_in)
def db_switch(sender, **kwargs):
user_db = 'userdb_%s' % kwargs['user'].username
cursor = connections[user_db].cursor()
The databases are defined in settings.py. Do I have to make this cursor global? Or is this all the way wrong way of doing it?
Thanks!
It's the wrong way of doing it.
Honestly I don't think there is a straightforward, stable way of doing this in Django. It's just not designed for it.
Instead, I'd set up a settings_username.py file for each user, which specifies a secondary database called personal or something. Then, after logging, have them redirect to a new domain, like username.example.com, which uses a unique .wsgi file that pulls in the settingsusername.py file.
Now, as far as the system is concerned, each website is totally separate and unique to that user. Just make sure to set the session cookie to example.com so that they're still logged in when they go to their user website.
So, I have an idea to build a web app. I am new to this business but am a programmer. I liked Python and thought let me start with Django. I ran into a problem with the built-in Django User Auth system as pointed by this question of mine on SO.
In short, I am using Django's built-in User auth and thought that it will easily fill my user field (the foreignkey) in my model but it does not. I have Googled and asked questions but only got a very convoluted answer or that I have to use the Admin section if I want anything like that.
My simple need is that whenever user saves anything in their profile, the user field should get populated so that I can reference it. To me, it sounds like the most basic need for any web app.
Am I wrong. I need advice. If Django is not good for this then I am ready to learn any other good framework or platform if need be.
In short, I am using Django's built-in
User auth and thought that it will
easily fill my user field (the
foreignkey) in my model but it does
not.
This won't just magically happen. You will have make it happen. Models are separated from the request so this would happen in your view, or a model method (perhaps save) that is passed the active user.
MVC / MTV design separates the database from the view / control logic. I don't see what framework has to do with this: unless you write the functionality yourself, the database doesn't know what to do with some User table and the currently logged in user (also separated from the data). Building in this functionality would inconvenience a lot of people as well...
In general, the python/django philosophy is: Explicit is better than implicit.
Now the solutions:
If you wanted this behavior in the view, for any form, you could potentially write:
instance = MyForm.save(commit=False) # commit=False prevents DB save.
instance.user = request.user
instance.save()
You could overwrite the save method on the model that accepts an optional user argument as well.
def save(self, *args, **kwargs):
user = kwargs.pop(user, None)
self.user = user
super(MyModel, self).save(*args, **kwargs)
mymodel = MyModel()
mymodel.save(user=request.user)