Django admin queryset foreign key to user django-allauth - python

I have an e-commerce development and I'm looking to send an email to the client from the admin site, I can´t the queryset correclty to do this. I have the following model:
models.py:
class Orden(models.Model):
cliente = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name='Usuario')
productos = models.ManyToManyField(OrdenProducto)
fecha_orden = models.DateTimeField(auto_now_add=True)
completada = models.BooleanField(default=False, null=True, blank=True)
id_transaccion = models.CharField(max_length=20, null=True)
correo_enviado = models.BooleanField(default=False, null=True, blank=True)
datos_pedido = models.ForeignKey(
'DatosPedido', on_delete=models.SET_NULL, blank=True, null=True)
pago = models.ForeignKey(
'Pago', on_delete=models.SET_NULL, blank=True, null=True)
cupon = models.ForeignKey(
'Cupon', on_delete=models.SET_NULL, blank=True, null=True)
class Meta:
verbose_name_plural = "Orden"
def __str__(self):
return self.cliente.username
cliente has a foreign key to the User model and I want to get the email address, I have tried many ways but I just can´t get it.
admin.py:
class OrdenAdmin(admin.ModelAdmin):
list_display = ('cliente', 'completada', 'correo_enviado')
actions = ['enviar_correo']
def enviar_correo(self, request, queryset):
queryset.update(correo_enviado=True)
a = queryset.get(cliente=self.user.email)
send_mail('test', 'test', 'xxxxxx#mail.com',
['a], fail_silently=True)

You can try iterating the queryset to access the specific data in the rows.
Try the following code.
class OrdenAdmin(admin.ModelAdmin):
list_display = ('cliente', 'completada', 'correo_enviado')
actions = ['enviar_correo']
def enviar_correo(self, request, queryset):
queryset.update(correo_enviado=True)
for obj in queryset:
email = obj.cliente.email
send_mail('test', 'test', email,
['a], fail_silently=True)
I hope this code helps you

Unless you have extended the default user model or have created Your Own user model, django default user model does not have an email field.
So if you have extended or created Your Own model you can do
myordenobj.cliente.email
But if you're using the default user model and your username is an email then do.
myordenobj.cliente.username

Related

Send id from one table to another automatically in form with ForeignKey in Django

#HELP in python (DJANGO 4)
I send this message here because I have not been able to find an answer elsewhere.
Currently I’m on a project where I have to create a booking form.
The goal is that when the user submit the Reservation form, I send the data in BDD, and I retrieve the user's id by a relation (ForeignKey).
And my difficulty is in this point precisely, when I send my form in BDD I recover the information, except the id of the user…
I did a Foreignkey relationship between my 2 tables and I see the relationship in BDD but I don’t receive the id of the User table, but null in the place….
Does anyone of you know how to help me please?
Thank you all.
--My model.py --
class Reservation(models.Model):
fullName = models.CharField('Nom Complet', max_length=250, null=True)
adress = models.CharField('Adresse', max_length=100, null=True)
zip_code = models.IntegerField('Code Postal', null=True)
city = models.CharField('Vile', max_length=100, null=True)
email = models.EmailField('Email', max_length=250, null=True)
phone = models.CharField('Telephone', max_length=20, null=False)
date = models.CharField('Date', max_length=20, null=True, blank=True)
hour = models.CharField('Heure', max_length=20, null=True, blank=True)
message = models.TextField('Message', null=True)
accepted = models.BooleanField('Valide', null=True)
created_at = models.DateTimeField('Date Creation', auto_now_add=True, null=True)
modified_at = models.DateTimeField('Date Mise Jour', auto_now=True, null=True)
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
def __str__(self):
return self.fullName
-- my views.py --
#login_required()
def user_new_reservation(request, pk=None):
user = User.objects.get(id=pk)
if request.method == 'POST':
form = ReservationForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Votre réservation a bien été envoyé!')
return redirect('reservation:user_reservation', pk=request.user.id)
else:
form = ReservationForm()
context = {'form': form}
return render(request, 'reservation/new_reservation.html', context)
-- My Form.py --
class ReservationForm(forms.ModelForm):
class Meta:
model = Reservation
fields = [
'fullName',
'adress',
'zip_code',
'city',
'email',
'phone',
'date',
'hour',
'message',
]
Thank you all.
Inside your form.save use:
user = form.save(commit=False)
user.user = request.user
user.save()
user=your field name in your model
request user= in django when you use authentication you can access some of information based on request like user and other
Good luck

Django: NOT NULL constraint failed: account_tutorvalidator.user_id

I am new to django and I created this "apply now form" exclusively for tutors that when they submit the form it will appear to the admin site, and I will manually check it if they are a valid tutor. And if they are a valid tutor, I will check the is_validated booleanfield in the admin site to the corresponding tutor that sent the form, so that he/she will have access to other things in the site. But I am having this problem that when you submit the form this comes up..
NOT NULL constraint failed: account_tutorvalidator.user_id
I have search for some solutions and also read similar questions here but I still couldn't understand what to do.. could someone help me out with this?
here is my models.py
class User(AbstractUser):
is_student = models.BooleanField(default=False)
is_tutor = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
phone_number = models.CharField(max_length=11, blank=False, null=True)
current_address = models.CharField(max_length=100, null=True)
image = models.ImageField(default='default-pic.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.first_name} {self.last_name}'
class TutorProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True,
related_name='tutor_profile')
bio = models.CharField(max_length=255, blank=True)
is_validated = models.BooleanField(default=False)
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}'s Profile"
class TutorValidator(models.Model):
user = models.ForeignKey(TutorProfile, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
dbs = models.ImageField(upload_to='dbs_pics')
driving_license = models.ImageField(upload_to='drivers_license_pics', null=True, blank=True)
national_id = models.ImageField(upload_to='national_id_pics', null=True, blank=True)
def __str__(self):
return f"{self.first_name}'s application form"
my forms.py
class TutorValidationForm(forms.ModelForm):
class Meta:
model = TutorValidator
fields = ['first_name', 'last_name', 'driving_license', 'national_id']
labels = {
'national_id': _('National ID')
}
my views.py
class TutorValidatorView(LoginRequiredMixin, FormView):
template_name = 'account/tutor_validator.html'
form_class = TutorValidationForm
success_url = '/'
The error is because TutorValidator requires that you set the user profile foreign key which your form currently does not support, so you need a way to set this to the object you are creating, and use the current logged in user (the one who is submitting the form).
You can do this by overriding form_valid. Try with:
class TutorValidatorView(LoginRequiredMixin, FormView):
...
def form_valid(self, form):
tutor_validator = form.save(commit=False)
tutor_validator.user = self.request.user.tutor_profile
tutor_validator.save()
return HttpResponseRedirect(self.get_success_url())
Note that the current user needs to already have an existing TutorProfile. Otherwise you need to create that first to connect it to TutorValidator

Unable to register user - TypeError: Direct assignment to the reverse side of a related set is prohibited. Use searches.set() instead

I've set up my models, serializers and viewsets in my Django REST API to assign a search record to a particular user, and to associate all the relevant user's searches to their record in the User model. It was all working fine, but I'm now getting the TypeError error message (in the subject line of this question) when I try to create a new user. I've listed the relevant models, serializers and viewsets below. Please could anyone take a look and let me know where I'm going wrong? Any help would be very much appreciated.
User serializer:
class UserSerializer(serializers.ModelSerializer):
searches = serializers.PrimaryKeyRelatedField(many=True, queryset=SearchHistoryModel.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'email', 'password', 'searches')
extra_kwargs = {'email': {
'required': True,
'validators': [UniqueValidator(queryset=User.objects.all())]
}}
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
return user
User viewset:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [permissions.AllowAny]
Search model:
class SearchHistoryModel(models.Model):
"""
Stores each user's search submission
"""
created_date = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, related_name='searches', on_delete=models.CASCADE)
cpu_component_name = models.CharField(max_length=10, blank=False)
cpu_subcomponent_name = models.CharField(max_length=50, blank=False)
motherboard_name = models.CharField(max_length=20, blank=False)
gpu_component_name = models.CharField(max_length=10, blank=True, null=True)
gpu_subcomponent_name = models.CharField(max_length=50, blank=True, null=True)
gpu_subcomponent_quantity = models.PositiveIntegerField(default=0)
ram_component_name = models.CharField(max_length=15, blank=True, null=True)
ram_component_quantity = models.PositiveIntegerField(default=0)
ssd_component_name = models.CharField(max_length=15, blank=True, null=True)
ssd_component_quantity = models.PositiveIntegerField(default=0)
hdd_component_name = models.CharField(max_length=20, blank=True, null=True)
hdd_component_quantity = models.PositiveIntegerField(default=0)
optical_drive_name = models.CharField(max_length=15, blank=True, null=True)
class Meta:
verbose_name = 'Search'
verbose_name_plural = 'Searches'
ordering = ['owner', 'created_date']
def __str__(self):
return '{}\'s search choices'.format(self.owner)
Search serializer:
class SearchHistorySerializer(serializers.ModelSerializer):
"""
Serializes the user's search history data passed into the SearchHistoryModel
Associates each search with the relevant user
"""
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = SearchHistoryModel
fields = (
'id', 'created_date', 'owner', 'cpu_component_name', 'cpu_subcomponent_name',
'motherboard_name', 'gpu_component_name', 'gpu_subcomponent_name',
'gpu_subcomponent_quantity', 'ram_component_name', 'ram_component_quantity',
'ssd_component_name', 'ssd_component_quantity', 'hdd_component_name',
'hdd_component_quantity', 'optical_drive_name'
)
Search viewset:
class SearchHistoryViewSet(viewsets.ModelViewSet):
queryset = SearchHistoryModel.objects.all()
serializer_class = SearchHistorySerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
In user = User.objects.create_user(**validated_data), validated_data contains a searches value which is an id.
But actually the ForeignKey is in the other sense : in Searches model, and to refer to a User instance, not the opposite.
To link a user to searches, it is not in User DB table that you write an id, but in Searches that you write a User id.
class UserSerializer(serializers.ModelSerializer):
(...)
def create(self, validated_data):
# Extract the value from 'validated_data'
search_ids = validated_data.pop('searches', None)
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
# Update existing search instances
for search_id in search_ids:
Search.objects.filter(id=search_id).update(owner=user)
return user

How to show all group content if user is a group member

i am new to programming and doing a small project(simple bug tracker) using django-rest-framework.
so far i have a Bugs model and if the user is logged in, he can see the bugs reported by him.Now i created a new model called Team in which one can make a team by adding email ids (i used MultiEmailField to store the list of emails).My requirement is that if the logged in user's email is present in any Team, the user should be able to see all the team members activities.I dont know how to accomplish this .please help me.Thanks in advance
#bugs model#
from django.db import models
from django.contrib.auth.models import User
class Bugs(models.Model):
issueId = models.PositiveIntegerField(primary_key=True)
projectName = models.CharField(max_length=300)
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100, unique=True)
description = models.TextField(max_length=3000, blank=True)
actualResult = models.TextField(max_length=1000, blank=True)
expectedResult = models.TextField(max_length=1000, blank=True)
status = models.TextField(max_length=30, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(
User, related_name="bugs", on_delete=models.CASCADE, null=True)
#team model#
from django.db import models
from multi_email_field.fields import MultiEmailField
from django.contrib.auth.models import User
class Team(models.Model):
projectTitle = models.CharField(max_length=300, blank=False, null=True)
durationFrom = models.DateField(null=True)
durationEnd = models.DateField(null=True)
teamMembers = MultiEmailField()
owner = models.ForeignKey(
User, related_name="team", on_delete=models.CASCADE, null=True)
#api.py#
from bugs.models import Bugs
from rest_framework import viewsets, permissions
from .serializers import BugsSerializer
class BugsViewSet(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = BugsSerializer
def get_queryset(self):
return self.request.user.bugs.all()
def perform_create(self, serializer):
serializer.save(owner=self.request.user)

How to display multiple objects from fields in Django Admin

I am a bit stumped as to how I can add multiple access_token and items_ids in Django Admin. The models and apps involved are as follows. This is my first post so please forgive if it isn't in proper format.
Trans/models.py
class Exchange(models.Model):
created = models.DateTimeField()
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='token', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True, default='')
item_id = models.CharField(max_length=300, blank=True, default='')
request_id = models.CharField(max_length=300, blank=True, default='')
class Meta:
ordering = ('item_id',)
I have setup a userprofile section for the admin:
Users/models.py
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True, null=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='public_token')
access_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='access_token')
item_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='item_ID')
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
class Meta():
db_table = 'user_profile'
users/forms.py
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('user', 'public_token', 'access_token', 'item_id',)
users/admin.py
class UserProfileAdmin(admin.ModelAdmin):
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id',)
ordering = ('user',)
list_select_related = ('user',)
admin.site.register(UserProfile, UserProfileAdmin)
class UserProfileAdminInline(admin.TabularInline):
model = UserProfile
I'm really just stumped as I tried making many to many field but couldnt seem to link correctly and or the process broke when testing in a sandbox environment. Any help would be greatly appreciated! In my case I need to record multiple access_tokens and item_ids for each user.
It's a little bit confusing what you are asking...particularly the way that your data model is setup....but I'm going to make a couple of assumptions in my answer (it would be helpful to better understand what you are trying to do at a high level).
I think what you are wanting to do is to be able to configure multiple Exchange objects per user profile...in which case I would set things up this way:
1. The related_name field on the FK to the user profile in the exchange model will be how you access multiple exchanges...so in this case you probably want a pluralized name.
2. To be able to edit multiple in the Django Admin you will need to setup an InlineAdmin object.
3. The CharFields that are actually ON the UserProfile will only ever be single fields...if you want multiple then you need to move them to another related object (like the Exchange model).
4. I don't think what you want here is a ManyToMany as that would imply user's would be sharing these tokens and item ids (or Exchanges?)...but maybe that is what you want...in which case you should change the ForeignKey to UserProfile from the Exchange model to a ManyToManyField. The rest of this post assumes you don't want that.
trans/models.py
from django.db import models
from django.conf import settings
class Exchange(models.Model):
class Meta:
ordering = ('item_id', )
created = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='exchanges', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True)
item_id = models.CharField(max_length=300, blank=True)
request_id = models.CharField(max_length=300, blank=True)
users/models.py
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
class Meta:
db_table = 'user_profile'
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True)
access_token = models.CharField(max_length=100, blank=True, null=True)
item_id = models.CharField(max_length=100, blank=True, null=True)
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
users/admin.py
from django.contrib import admin
from trans.models import Exchange
from users.models import UserProfile
class ExchangeAdminInline(admin.TabularInline):
model = Exchange
class UserProfileAdmin(admin.ModelAdmin):
inlines = (ExchangeAdminInline, )
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id', )
ordering = ('user', )
list_select_related = ('user', )
admin.site.register(UserProfile, UserProfileAdmin)
There is a lot that you can do to configure the inlines to behave how you want...but that's the basics.

Categories