Как передать данные в поле ManyToManyField из представления в django
Здравствуйте, я новичок в django и я пытаюсь создать страницу, где мы можем добавлять и участвовать в различных событиях.
Это модель, которую я создал для своей базы данных
model.py
class Venue(models.Model):
name = models.CharField('Venue Name', max_length=120)
address = models.CharField(max_length=300)
zip_code = models.CharField('Zip Code', max_length=6)
phone = models.CharField('Contact Number', max_length=25, blank=True)
web = models.URLField('Website Address', blank=True)
email = models.EmailField('Email', blank=True)
owner = models.IntegerField('Venue Owner', blank=False, default=1)
venue_image = models.ImageField(null=True, blank=True, upload_to="images/")
class Event(models.Model):
name = models.CharField('Event Name', max_length=120)
event_date = models.DateTimeField('Event Date')
venue = models.ForeignKey(Venue, blank=True,null=True, on_delete=models.CASCADE)
manager = models.ForeignKey(User,blank=True,null=True,on_delete=models.SET_NULL)
description = models.TextField(blank=True, )
attendees = models.ManyToManyField(User,blank=True, related_name='attendees')
здесь я пытаюсь сделать ссылку, нажав на которую пользователь участвует в этом событии. но я не понимаю, как поместить данные пользователя в вышеуказанное поле attendees
функция просмотра
def attendees(request):
Event.attendees.add(request.user)
return redirect('list-events')
error : AttributeError at /participate/ Объект 'ManyToManyDescriptor' не имеет атрибута 'add'
ссылка
<a href="{% url 'participate' %}">Participate</a>
url.py
path('participate/', attendees, name='participate')
Вам необходимо указать, для какого события будет добавлен пользователь, поэтому представление должно выглядеть следующим образом:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_POST
@require_POST
@login_required
def attendees(request, pk):
event = get_object_or_404(Event, pk=pk)
event.attendees.add(request.user)
return redirect('list-events')
участие должно осуществляться через POST-запрос, поскольку он изменяет сущности. Запрос GET должен использоваться только для получения данных, а не для их обновления.
и urls.py
, таким образом, должен содержать параметр URL для первичного ключа:
path('participate/<int:pk>/', attendees, name='participate')
Наконец, шаблон должен сделать POST-запрос к пути с первичным ключом события:
<form method="post" action="{% url 'participate' pk=event.pk %}">
<button type="submit">Participate</button>
<form>
Примечание: Вы можете ограничить представления для аутентифицированных пользователей с помощью декоратора
@login_required
декоратора [Django-doc].
Примечание: Можно использовать декоратор
@require_POST
[Django-doc]. для ограничения доступа к представлению только для POST запроса.
Примечание: Обычно лучше использовать
settings.AUTH_USER_MODEL
[Django-doc] для ссылки на модель пользователя, чем использоватьUser
модель [Django-doc] напрямую. Для получения дополнительной информации вы можете посмотреть ссылка наUser
модель раздел документации .
Вот самый простой способ сделать это. Насколько я могу понять Venue
модель сохраняется администратором (т.е. вами). Если нет, то вы должны сначала сохранить Venue.
Теперь ключевым моментом является то, что в поля отношений вы должны передать весь наследуемый объект модели.
Вы можете сделать примерно следующее:
#in login view
def login(request):
#your code
request.session['userID']=userID
#your code
теперь вы можете использовать переменную сессии (т.е. userID) в любом представлении или шаблоне
#participate view
from mymodels import Event,Venue
def participate(request):
#your GET or POST parameters here
user=user_model.objects.get(id=request.session['userID'])
venue=Venue.objects.get(id=venue_id) #OR filter it by any other field like name
E1=Event()
E1.attendees= user
E1.venue= venue
E1.manager= user
E1.name= name_from_request_parameters
E1.description= description_from_request_parameters
E1.event_date= event_date_from_request_parameters
E1.save()
Совет: используйте текущую дату по умолчанию в поле даты, например
event_date = models.DateTimeField(default=datetime.now())