Как я могу запросить Django Models с Foreign и OneToOneFields для значений полей
В моем проекте есть следующие Django Models: Event, Ticket, Pin и Guest. Как я могу запросить эти таблицы, чтобы получить имя Event Name, на которое зарегистрировался вошедший пользователь-гость. Ниже приведен мой код. Мои модели:
class Event(models.Model):
event_name = models.CharField(max_length=100)
date = models.DateField(auto_now_add=False, auto_now=False, null=False)
event_venue = models.CharField(max_length=200)
event_logo = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images')
added_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.event_name}"
#Prepare the url path for the Model
def get_absolute_url(self):
return reverse("event_detail", args=[str(self.id)])
#Ticket Model
class Ticket(models.Model):
event = models.ForeignKey(Event, on_delete=models.CASCADE)
price = models.PositiveIntegerField()
category = models.CharField(max_length=100, choices=PASS, default=None, blank=True, null=True)
added_date = models.DateField(auto_now_add=True)
def __str__(self):
return f"{self.event} "
#Prepare the url path for the Model
def get_absolute_url(self):
return reverse("ticket-detail", args=[str(self.id)])
def generate_pin():
return ''.join(str(randint(0, 9)) for _ in range(6))
class Pin(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
added = models.DateTimeField(auto_now_add=True, blank=False)
reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
status = models.CharField(max_length=30, default='Not Activated')
#Save Reference Number
def save(self, *args, **kwargs):
self.reference == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.ticket
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket}"
def get_absolute_url(self):
return reverse("pin-detail", args=[str(self.id)])
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
pin = models.CharField(max_length=6, default='No Pin', blank=True)
def __str__(self):
return f"{self.guest_name}"
Я действительно запутался в том, как выполнить этот запрос. Я пробовал guest_event = Pin.objects.filter(guest__guest_name__icontains=request.user)
, но никак, потому что я думаю, что .get() - это выход, но не могу понять, так что кто-нибудь должен помочь, даже если это будет реструктуризация базы данных для меня, чтобы получить решение. Спасибо
У вас нет FK для связи гостевой таблицы с другими таблицами, pin на вкладке Guest является CharField, если вы измените его на FK поле, вы можете запросить его в зависимости от схемы вашей таблицы
Спасибо @Vaibh Vaibhav lodha, ваш комментарий дал мне идею, как разобраться в этом, и это сработало. Вот как я реструктурировал свою гостевую модель:
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
ticket = models.OneToOneField(Ticket, on_delete=models.CASCADE, blank=True)
def __str__(self):
return f"{self.guest_name}"
и в представлениях я использовал pin = request.session['pin']
для установки значения PIN в качестве сессии и получил его в представлении register_guest pin = request.session.get('pin')
и оттуда я смог сверить значение PIN из сессии с тем, что есть в модели PIN через try and except DoesNotExist, как показано ниже:
try:
pin_detail = Pin.objects.get(value = pin)
except Pin.DoesNotExist:
messages.error(request, 'PIN Does Not Exist')
return redirect('pin-activation')
else:
#Guest User Registration Form
form = GuestUserForm()
page_title = "Festival Registration"
if request.method == 'POST':
form = GuestUserForm(request.POST)
#Check if Form contains valid data
if form.is_valid():
#Save the Guest User Form to get an instance of the user
new_user = form.save()
#Create A New Guest with his PIN
Guest.objects.create(guest_name=new_user, ticket=pin_detail.ticket)
#Filter and update PIN
Pin.objects.filter(value=pin).update(status='Activated')
#Delete the PIN Session from the requet
del request.session['pin']
#Send User Message
messages.success(request, 'Registered Successfully. Login')
return redirect('user-login')
else:
form = GuestUserForm()
context = {
'form':form,
'page_title':page_title,
}
return render(request, 'user/register.html', context)
Вот как я сохранил имя события в модели гостя с помощью запроса create: Guest.objects.create(guest_name=new_user, ticket=pin_detail.ticket)
Для получения имени события я использовал pin_detail.ticket
, поскольку pin_detail должен использовать метод .get()
в запросе, затем я также использовал атрибут PIN (ticket) из запроса, чтобы получить билет на событие, связанный с PIN.
Для получения события Logged in Guest User Event я сделал следующее в моем представлении index:
try:
guest_user = Guest.objects.get(guest_name = request.user)
guest_event = guest_event.ticket
except Guest.DoesNotExist:
messages.error(request, 'Guest Does Not Exist')
return redirect('user-login')
else:
context = {
'guest_event':guest_event,
}
return render(request, 'user/profile.html', context)
Меня поправят, если я не решил проблему, используя лучший подход. Спасибо