Specify field to be rendered in the django admin - python

I use the default User class from from django.contrib.auth.models import User. In the user creation when the user is created I set the username field to a random hash. When I use the model in ManyToMany field and use it in the Django admin then the random hash is rendered in the select box. Is there a way to specify the field to be taken from the model to be displayed in the select box so that I can specify the model as ManyToMany field and use the email to be rendered in the django admin form.
class TestModel(models.Model):
group = models.ManyToManyField(Group, null=True)
user = models.ManyToManyField(User, null=True)
Is there a field like the display_name that can be passed to the model field so that the appropriate field can be taken from the ManyToMany model for rendering. I am using Django 1.5.5

I think you need to do something like this,
class TestModelAdminForm(forms.ModelForm):
user = forms.MultipleChoiceField(choices=[ (user.id, user.email) for user in User.objects.all()])
class Meta:
model = TestModel
fields = ('user','group')
class TestModelAdmin(admin.ModelAdmin):
form = TestModelAdminForm

Related

Show fields passing through a ManyToMany field django admin

I'm working on a project developed in Python 2.7 and Django 1.11.
I'm trying to show in admin page two fields passing through a ManyToMany field.
Here the models:
class ModelZero(Model):
# some fields
mtm_field = models.ManyToManyField(to="ModelOne", through="ModelTwo")
class ModelOne(Model):
# some fields
field_1_1 = models.CharField(unique=True, max_length=200)
field_1_2 = models.BooleanField(default=True)
class ModelTwo(Model):
# some fields
field_2_1 = models.ForeignKey('ModelOne', on_delete=models.CASCADE)
field_2_2 = models.BooleanField(default=True)
In the ModelZero admin page I want to show some fields from the ModelZero itself plus field_2_1 and field_2_2 from ModelTwo.
More in detail, the field_2_1 should be present using a custom widget.
Please note that ModelZeroAdmin is an inline ones.
Here the admin page:
class ModelZeroAdmin(DynamicRawIDMixin, admin.TabularInline):
model = ModelZero
fields = ('some', 'fields', 'field_2_2')
form = forms.ModelZeroForm
def field_2_2(self, obj):
return obj.mtm_field.through.field_2_2
Here the form:
class ModelZeroForm(ModelForm):
class Meta:
widgets = {
"mtm_field.through.field_2_1": dal.autocomplete.ModelSelect2Multiple(
url="my-autocomplete-url"
)
}
In this way i have two errors:
it's not possible add custom fields (field_2_2) in the fields tuple
custom widget is not showed
Is there a way to achieve this goal using this models structure?
I don't have experience with older Django version, but if I am not mistaken the syntax for a related field in admin interface would be something like :mtm_field__field_2_2.

How to add 'mobile' field to default auth_user table in User model in django?

I want to add Mobile filed to be saved to auth_user table when i register.
models.py
from django.db import models
from django.contrib.auth.models import User
class UserRegModel(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile = models.CharField(max_length=100)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
mobile = forms.CharField(max_length=15)
class Meta:
model = User
fields = ['username','email','mobile','password1','password2']
If you want to store all user data together, you should substitute a user model instead of creating a OneToOne relationship. Judging by the current code you will get 2 tables - one for standard Django user and one connected to it with mobile data.
Here you can read more about substituting a user and the difference between these 2 approaches:
Extending the User model with custom fields in Django
Or directly in the documentation:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
Click here for the first image
Click here for the second image
Do this and type these codes in terminal
python manage.py makemigrations
python manage.py migrate

How can I get the data of the modelform?

I am building a user model and wanna attach it to a modelform as below shown. How can I get the email of each user by shell accessing the mysql database?
I have tried these to get the data by shell, but the previous one said the object has no email attribute and the latter one said the forms.py has no object.
from Project.User.models import UserProfile as p
p.objects.filter(is_active=True).first().email //
from Project.User.forms import ClientProfileForm as p
p.objects.filter(is_active=True).first().email
Code:
models.py:
class UserProfile(BaseModel):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE, verbose_name='client')
name = models.CharField('name',max_length=30, null=False, help_text="Name")
gender = models.CharField('sex',max_length=1, help_text="Sex")
class Meta:
verbose_name = 'Client'
verbose_name_plural = 'Client'
def __str__(self):
return 'client:%s' % self.user
forms.py:
class ClientProfileForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = UserProfile
fields = ("user", "name", "gender")
Have you tried using
p.objects.filter(is_active=True).first().user.email
There is no data in form before you send a data to it so you can't get the user and it's email from your shell.
Forms are used to get data from HTML templates for example and validate that data and then add those data to the database.
If you fill a form, you can access the data that has been cleaned from your view like this:
form = ClientProfileForm(request.POST)
if form.is_valid():
print(form.cleaned_data['my_form_field_name'])
Also you can set some default values for forms. Example here:
Django forms initial example on stackoverflow
And finally for your problem:
You are trying to access email from UserProfile which doesn't have a email field but the User model does.
so you can access the email like this:
from Project.User.models import UserProfile as p
# Get the first profile and then get the email from user model
p.objects.filter(is_active=True).first().user.email
from Project.User.forms import UserProfile as p
This line is incorrect because the name of your form is ClientProfileForm and not UserProfile. This is why you are getting the error forms.py has no object

Issues with OneToOne Field in Serializer in django rest framework

I have model UserProfile related with User Model via one-to-one relationship.
UserProfileSerializer is defined correctly and it serializes userprofile object well.
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
country = models.CharField(max_length=255)
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('user','country')
But it gives error {'user':['This field is required']} on passing data.
>>> s = UserProfileSerializer(data = {'user':1,'country':'YY'} )
>>> s.is_valid()
False
>>> s.errrors
{'user':['This field is required']}
This might be too late to help, and I'm not sure exactly what you're trying to do, but try setting the user field in your serializer to use a PrimaryKeyRelatedField so that you can represent a User with an ID, or set the user field to be readonly if you only want to update UserProfile things. If you don't want to use a primary key, other relationship fields are here.
If you change the user field to be a PrimaryKeyRelatedField and you want the user data to return as it is now, you might want to make two UserProfile serializers - one for write operations, and one for reading. After a create or an update, you can switch to the read serializer to populate the response.

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