I have just added a new field to one of my models, I have deleted and recreated my database, but when I enter info into the new field, nothing appears to have saved for that field, but the others have.
The field looks like this
class Author(models.Model):
display_name = models.CharField(unique=True,max_length=30)
first_name = models.CharField(max_length=15)
phone = models.CharField(max_length=15, blank=True)
twitter_handle = models.CharField(max_length=20, blank=True)
And I have included it into the fields list in forms.py
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ['display_name','first_name','twitter_handle','phone']
Any ideas what could be causing this?
Any help appreciated
The code looks fine. Can you provide the rest of your code?
Some databases require that you define a primary_key - depends on your other PKs in the model
Try adding primary_key=True to your display_name field and see if it helps
FIXED
Due to a complex interaction between two forms that are submitted at the same time with various validation constraints, I manually populate the models from the forms in a views function, and I had forgotten to add the twitter_hanle to this, oops sorry, hopefully this will help if someone makes the same oversight.
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 keep getting an error
ImproperlyConfigured at /messages/compose/
Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited; form ComposeForm needs updating.
I totally understand what the error is pointing out however I don't understand why it's showing up in the first place?
Here is the form django wants me to update:
from django import forms
from .models import DirectMessage
class ComposeForm(forms.ModelForm):
class Meta:
model = DirectMessage
and here is my model (complete with fields):
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
user_obj = User.objects.get(username = 'jess')
class DirectMessage(models.Model):
subject = models.CharField(max_length =150)
body = models.CharField(max_length =3000)
sender = models.ForeignKey(User, related_name='sent_direct_messages', null=True, blank=True)
receiver = models.ForeignKey(User, related_name='recieved_direct_messages', null=True, blank=True)
sent = models.DateTimeField(auto_now_add=False, auto_now=False, null=True, blank=True)
read = models.DateTimeField(auto_now_add=False, auto_now=False, null=True, blank=True)
def __unicode__(self):
return self.subject
perhaps there is a problem with my syntax or I'm missing a glaring fundamental error. Any help would be appreciated, let me know if you need any more information/context. Thank you!
I totally understand what the error is pointing out however I don't
understand why it's showing up in the first place?
Err... Because your ModelForm doesn't explicitely specifies either a fields list or an exclude list ?
Here is the form django wants me to update:
class DirectMessageAdmin(admin.ModelAdmin):
This is not a ModelForm, this is a ModelAdmin. Given the url in your error message I don't think it has anything to do with your admin...
As it is described in Django documentation: Creating forms from models: Selecting the fields to use:
It is strongly recommended that you explicitly set all fields that should be edited in the form using the fields attribute. Failure to do so can easily lead to security problems when a form unexpectedly allows a user to set certain fields, especially when new fields are added to a model. Depending on how the form is rendered, the problem may not even be visible on the web page.
The alternative approach would be to include all fields automatically, or blacklist only some. This fundamental approach is known to be much less secure and has led to serious exploits on major websites (e.g. GitHub).
Therefore, you should explicitly include a fields variable in your Meta, regardless of the fields defined in the model. This has to be a tuple of all fields of the model which you need to have in the ModelForm. You can alternatively specify the value as '__all__'.
This has been introduced in Django 1.6:
Changed in Django 1.6:
Before version 1.6, the 'all' shortcut did not exist, but omitting the fields attribute had the same effect. Omitting both fields and exclude is now deprecated, but will continue to work as before until version 1.8.
I've got a weird problem in django admin list_display. Whenever I add a foreign key to a list_display the whole change list view goes blank showing only the total no of entries.
models.py:
class Organization(models.Model):
org_id = models.AutoField(primary_key=True)
org_name = models.CharField(max_length=288)
def __unicode__(self):
return self.org_name
class Meta:
db_table = u'organization'
class Server(models.Model):
server_id = models.AutoField(primary_key=True)
server_name = models.CharField(max_length=135,verbose_name="Server Name")
org = models.ForeignKey(Organization,verbose_name="Organization")
def __unicode__(self):
return self.server_name
class Meta:
db_table = u'server'
admin.py:
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name','org')
admin.site.register(Server,ServerAdmin)
Now I'd expect this code to show me the organization name in the ChangeList View, But instead I get this:
If I remove the org in the list_display of ServerAdmin class, I get this:
I didn't modify the template or override any ModelAdmin methods. I'm using Mysql(5.1.58) as my database that comes with ubuntu 11.10 repository.
I'll be really glad if I could a get a sloution for this problem guys. Thanks in advance.
I second Stefano on the fact that null=True, blank=True is to be added. But, I think you only need to add it to the org_name field of the Organization model. That should make your way through. It has to be done because you have run inspectdb to create models from your legacy DB. And probably the organization table in the DB has an empty string stored. So, adding the above would allow the Admin to have a blank field/column displayed.
Moreover, you can also try using callbacks in situations where you don't want to make changes to your model definition like the above.
Try adding null=True, blank=True to all your model fields.
Usually django admin will silenty fail (thus show no records in the list) if the row does not validate the model constraints.
See: https://stackoverflow.com/a/163968/1104941
Does the following work for you?
admin.py:
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name','org__org_name')
admin.site.register(Server,ServerAdmin)
I had a similar problem and solved it like this (using your example):
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name', 'get_org')
def get_org(self, obj):
return obj.org.org_name
get_org.short_description = 'Org'
admin.site.register(Server,ServerAdmin)
I am working on creating a simple contest submission system using django. This is my first real django project. Basically each user can view a list of problems, submit a file, and view a results page.
Each problem can be associated with multiple contests, and different contests can use the same problem. Because of this, both problem and contest have a manyToManyField with each other. This is what is causing my problem.
Here is the initial models.py implementation I am going with:
startfile
from django.db import models
class User(models.Model):
username = models.CharField(max_length=50)
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
class Problem(models.Model):
name = models.CharField(max_length=50)
filename = models.CharField(max_length=300)
contests = models.ManyToManyField(Contest)
class Contest(models.Model):
name = models.CharField(max_length=50)
problems = models.ManyToManyField(Problem)
date = models.DateField()
class Submission(models.Model):
user = models.ForeignKey(User)
problem = models.ForeignKey(Problem)
filename = models.CharField(max_length=300)
endfile
Is there a simple way to fix this? Or should I rethink my entire layout? I tried breaking each class into its own django app but I don't think thats how I should do it. The error I get is that Contest can not be found (because it exists lower in the file).
All advice is appreciated!
You don't need a ManyToManyField in both Contest and Problem. Many-to-many fields are already bidirectional. Just put it on one - doesn't matter which.
Djano will automatically create the reverse relation for you, so you only need to create it one end, eg.
class Problem(models.Model):
name = models.CharField(max_length=50)
filename = models.CharField(max_length=300)
contests = models.ManyToManyField(Contest, related_name='problems')
related_name gives you the possibility to assign a name to the reverse relation. Without defining the relation on the Contest model, you can then access eg. a_contest.problems.all()!