In Django Project I am using two databases, first is MySQL second is PostgreSQL, in PostgreSQL I have only geometric values but I need users too, so In models I have:
from django.conf import settings
from django.contrib.gis.db import models
class geo(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
location = models.PointField()
Everything is working fine but when I try to save, user field shows an error user instance with id 1L does not exist So what could be the answer? Is problem coming from the router.py file?
The error comes from this line :
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
Here you are defining default=1 so when you are not assigning any user instance to user field of geo model, default then user field is taking integer default value, but it is expecting a user instance.
There are two solutions :
At the time of creation of new instance/record of geo model, add a user instance to it.
Or
Use blank=True, null=True in your geo model,like this:
class geo(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
location = models.PointField()
I would personally recommend the second method. Thanks.
Related
So I know that Django has a built in system with the User, and it contains things like Username, e-mail, password, and first and last name. I want to know how I can utilise this in my site.
So I have a first_name and last_name field in the models.py file, and they are CharFields. I want to know how to connect them to the already existing UserForm that comes with Django.
I have tried a few things already, such as doing this with the models.py file.
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.OneToOneField(User, on_delete=models.CASCADE)
Here is some code for the form.py file.
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password','first_name')
As you can see from the form, I added the first_name attribute, and in the models.py file, I have the first_name connected with the forms.py one. I am now getting this error.
HINT: Add or change a related_name argument to the definition for 'UserProfileInfo.user' or 'UserProfileInfo.first_name'.
So I added a related name field to the model, as shown here
first_name = models.OneToOneField(User, on_delete=models.CASCADE,related_name='first_name')
But, wouldn't you know it, I got yet another error:
ValueError: Cannot assign "''": "User.first_name" must be a "UserProfileInfo" instance.
I don't really know what is going on here.
So I expected to get no errors, just like the user field. Instead I got this error. Any help would be greatly appreciated :)
Your code is setting a OneToOne to the User model for both the user and first_name fields. So this means the related field will be User.id for both.
To specify that you want UserProfileInfo.first_name to map to User.first_name you will need to set to_field=first_name
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.OneToOneField(User, on_delete=models.CASCADE, to_field='first_name', related_name='user_profile_first_name')
However, this will still cause an issue as you can only set a OneToOne relationship to a unique field. As User.first_name is not unique, you cannot set a OneToOne relationship to it.
If both the OneToOne relationships are referencing the same object, one of the relationships is redundant as you can access the fields on that object through the other relationship. It would be better to have a method on UserProfileInfo that gets the first name through the user field.
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def get_first_name(self):
return user.first_name
You will also need to set signals to create/update UserProfileInfo when User is created/updated. Have a look at this article.
There are also other ways to extend the User model in Django. Have a look at this article or this answer for suggestions.
But if you're not adding any extra fields to the User model, it may be better just to use it directly.
I am creating my own users, Restaurant and Customer. I have extended the AbstractUser class and then created a OneToOneField field for each user. I am wondering if I need to add the AUTH_USER_MODEL in my settings.py. And also wondering what that does exactly...
What I was planning on doing was adding to my settings.py:
AUTH_USER_MODEL = 'myapp.Customer','myapp.Restaurant'
Do I have the right idea here?
My models.py:
class User(AbstractUser):
is_restaurant = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Restaurant(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
restaurant_name = models.CharField(max_length=50)
def __str__(self):
return self.restaurant_name
class Customer(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.user.get_full_name()
No. AUTH_USER_MODEL isn't expecting a tuple, so this won't work.
In any case, Restaurant and Customer are not your user model; your subclassed User is. That's what you should be putting in that setting.
I would suggest create single user table instead of three different tables and add type as restaurant, customer, admin etc. And add only one table into settings file. this won't lead any further issues authentication etc. Having single user table is always robust. In your case having three tables seems not good to maintain.
========== UPDATE ===========
Create model for user named as CustomUser (or name which you feel better) and extends to User Model of Django using AbstractBaseUser,PermissionsMixin. like
class CustomUser(AbstractBaseUser): have all fields which user table has already. and add your desired table to bifurcate type of restaurant and
customer have type field with choices option.
For further help you can check section https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model
I have the below in my models.py file:
class Film(models.Model):
title = models.CharField(max_length=200)
director = models.CharField(max_length=200)
description = models.CharField(max_length=200)
pub_date = models.DateField('date published')
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
When I logged into Django admin I added some films, and then added some comments, selecting which film object the comment related to. I then created a couple of users via the admin panel also.
I would like my relationships to be:
Film can have many comments / Comments belong to film
User can have many comments / Comments belong to user
I think, like with comments and films, I just need to define user as a foreign key to comment. I am struggling to do this. I am working through the Django tutorials but I can't see the tutorials covering how I can link other tables to the user.
I thought I would be able to do something like this:
user = models.ForeignKey(User, on_delete=models.CASCADE)
While importing User like this:
from django.contrib.auth.models import User
The result at the moment is if I keep user = models.ForeignKey(User, on_delete=models.CASCADE) I get err_connection_refused
Maybe have you changed your default user model in the settings?
Instead of using User directly with the the Foreign key, you should use user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) in your Comment Model, as follow
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
You need to apply migrations to be able to add user to Comment,
python manage.py makemigrations
python manage.py migrate
if at the moment that you are applying migrations, shell shows a message telling You are trying to add a non-nullable field 'user' to comment without a default
You have 2 Options
Skip migrations and add a default value to the field in the models or set the attribute as nullable, whatever else that you need
ie
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
and apply migrations again
Or select a default value to the new field, should be an id of an existing user in databse
This is because django should populate existing records in database, if exist
Use "settings.AUTH_USER_MODEL".
So, import "settings" from "django.conf", then use "settings.AUTH_USER_MODEL" as shown below:
from django.db import models
from django.conf import settings # Here
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
# Here
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
I've got a two part question regarding Django Admin.
Firstly, I've got a Django model Classified that has a foreign key field from another table Address. On setting data, I've got no issues with any of the fields and all fields get saved correctly.
However, if I want to edit the foreign field in the entry in Classified, it doesn't display the old/existing data in the fields. Instead it shows empty fields in the popup that opens.
How do I get the fields to display the existing data on clicking the + so that I can edit the correct information?
Secondly, I'm sure I've seen search fields in Django Admin. Am I mistaken? Is there a way for me to implement search in the admin panel? I have over 2 million records which need to be updated deleted from time to time. It's very cumbersome to manually go through all the pages in the admin and delete or edit those.
Adding Model Code:
Classified
class Classified(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=256)
contact_person = models.CharField(max_length=300, blank=True)
email = models.CharField(max_length=100, blank=True)
address = models.ForeignKey(Address)
subcategory = models.ForeignKey(Subcategory)
Address
class Address(models.Model):
id = models.AutoField(primary_key=True)
build_add = models.CharField(max_length=255)
street_add = models.CharField(max_length=255)
area = models.CharField(max_length=255)
city = models.ForeignKey(Cities)
The + means just that - add a new instance of the related object and relate the object you're editing to that. Because you're adding a new object it will be blank to start. If you want to be able to edit existing related objects from another object's admin you need to use inlines.
In your app's admin.py have something like:
from django.contrib import admin
from yourapp.models import Address, Classified
class AddressInline(admin.TabularInline):
model = Address
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
admin.site.register(Classified, ClassifiedAdmin)
Adding search from there is really easy.
...
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
search_fields = [
'field_you_want_to_search',
'another_field',
'address__field_on_relation',
]
...
Note the double underscore in that last one. That means you can search based on values in related objects' fields.
EDIT: This answer is right in that your foreignkey relationship is the wrong way round to do it this way - with the models shown in your question Classified would be the inline and Address the primary model.
Experimenting with django, I am trying to design a site that will reference registered users of the site as well as non-registered users. Trying to figure out how to best design my models for this, I'd like to give the non-registered user the ability to register and have it linked to the information I already have. I've read some other SO questions that are sort of related so I know I should be using a seperate class (registered & non-registered), but how would I reference 2 different models using a one foreign key?
Models.py:
from django.db import models
from django.contrib.auth.models import User
class NonRegisteredPerson(models.Model):
first_name = models.CharField(max_length=20, default='')
last_name = models.CharField(max_length=20, default='')
email = models.EmailField(max_length=20,default='', blank=True)
class Seat(models.Model):
num = models.CharField(max_length=100, blank=True)
# For the Non Registered User
occupant = models.ForeignKey('NonRegisteredPerson')
# For the Registered User - using Built-in User
occupant = models.ForeignKey(User)
How do I get "occupant" to reference NonRegisteredPerson and User?
Don't know if this matters, but the way I would handle if a NonRegisteredUser signs up for the site, is check if their e-mail exists in the NonRegisteredPerson model, if it does then delete them from that model and add to the Built-in User.
I know this must be a common scenario, but I don't know what or where I should be looking up for this. TIA.