我正在使用Django构建一个事件平台,其中包含一些事件 public 和一些 invite -only。以下是它的基本工作原理:
每个活动都基于活动模型。
私人活动只有受邀嘉宾才能看到:这是实现的 通过邀请模型引用事件和访客。
用户可以告知他们是否参加活动 通过存储相关事件的答案模型,用户 和答案。
答案和邀请模型完全相互独立,这样我就可以使用答案模型公共和私人活动。
我想要实现的目标:
对于我受邀的每个活动,请显示邀请(event.creator邀请您加入event.name),如果存在,则显示我的相关答案,否则显示要回答的表单。
所以我认为我想要做的就是让所有事件都被我邀请(我没有问题)并加入我的答案(用户=我)。问题是答案可能还不存在 - 如果我没有回答。
理想情况下,我会在一个查询中拥有所有这些,以便我可以在模板中执行类似的操作:invite_event.answer并显示答案(如果存在)。
所以我认为我最终需要的是混合两个查询:一个获取我被邀请的所有事件(1),另一个获取这些事件的所有答案(2)。
(1)
latest_events_invited = Event.objects.filter(invite__user_invited=request.user)
(2)
answers_events_invited = Answer.objects.filter(user_answering=request.user, event__in=latest_events_invited)
类似于:对于latest_events_invited中的每个事件,附加来自answers_events_invited的相应答案。
有什么想法吗?
代码:
我的模板(index.html):
<h3>Invites</h3>
{% if latest_invites_list %}
<ul>
{% for event in latest_events_invited %}
<li>
{{ event.creator }} invited you to {{ event }}<br/ >
<!--IDEALLY:-->
{% if event.answer %}
You answered: {{ answer.answer }}
{% else %}
<form action="{% url 'events:answer_event' invite.event.id %}" method="post">
{% csrf_token %}
Answer:
<select name="answer">
<option value="1" >Attending</option>
<option value="2" >Not attending</option>
</select>
<input type="submit" name="submit" value="Answer">
</form>
{% endif %}
</li>
</ul>
{% else %}
<p>No invites.</p>
{% endif %}
视图(views.py)
def index(request):
if request.user.is_authenticated():
latest_events_invited = Event.objects.filter(invite__user_invited=request.user)
latest_answers_list = Answer.objects.filter(user_answering=request.user, event__in=latest_events_invited)
#do something with those to get: "latest_events_invited_with_answers"
context = {'latest_events_invited':latest_events_invited, 'latest_answers_list':latest_answers_list}
else:
[...]
return render(request, 'events/index.html', context)
和模特。
事件
class Event(models.Model):
PRIVACY_CHOICES = (
(0, 'Public'),
(1, 'Invite only'),
)
name = models.CharField(max_length=200)
[...]
privacy = models.PositiveSmallIntegerField(max_length=1, choices=PRIVACY_CHOICES, default=0)
invited = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Invite', related_name='events_invited', blank=True)
answers = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Answer', related_name='events_answered', blank=True)
邀请
class Invite(models.Model):
user_invited = models.ForeignKey(settings.AUTH_USER_MODEL)
event = models.ForeignKey(Event)
created = models.DateTimeField(default=timezone.now, editable=False)
class Meta:
unique_together = (("user_invited", "event"),)
答案
class Answer(models.Model):
ANSWER_CHOICES = (
(1, 'Attending'),
(2, 'Not attending'),
)
user_answering = models.ForeignKey(settings.AUTH_USER_MODEL)
event = models.ForeignKey(Event)
answer = models.PositiveSmallIntegerField(max_length=1, choices=ANSWER_CHOICES)
class Meta:
unique_together = (("user_answering", "event"),)
希望有人可以帮助我 感谢。
答案 0 :(得分:0)
一个选项是在邀请某人时自动添加答案,默认为“否”。使用邀请的post_save信号或覆盖保存方法,这样您就不必每次都创建相关的答案。 / p>
另一种选择,可能更好,是在视图中而不是在模板中执行逻辑。检查答案是否存在;如果是,则传递模板的答案列表;如果没有,请传递一个空列表。
编辑:或者,更好的是:
在视图中:
try:
user_answer = Answer.objects.filter(user_answering = request.user).filter(event=event)
except ObjectDoesNotExist:
answer = None
EDIT2:或者怎么样:
Answer.objects.filter(user_answering = request.user).filter(event__in=Event.objects.filter(user__in = event.invited))
答案 1 :(得分:0)
好的,所以我明白了。我不知道这是否是最佳解决方案,但它现在有效 最后,它只有2个查询,我与for循环结合。
这是代码:(views.py)
def index(request):
if request.user.is_authenticated():
latest_events_invited = Event.objects.filter(invite__user_invited=request.user)
latest_answers_for_events = Answer.objects.filter(user_answering=request.user, event__in=latest_events_invited)
for event in latest_events_invited:
for answer in latest_answers_for_events:
if answer.event.id == event.id:
event.answer = answer.answer
else:
event.answer = ''
context = {'latest_events_invited': latest_events_invited,}
return render(request, 'events/index.html', context)
然后我可以直接在模板(index.html)中访问答案,如下所示:
{{ event.answer }}