国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > Django實(shí)戰(zhàn)教程: 開發(fā)餐廳在線點(diǎn)評網(wǎng)站(1)

Django實(shí)戰(zhàn)教程: 開發(fā)餐廳在線點(diǎn)評網(wǎng)站(1)

時(shí)間:2023-05-29 04:33:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2023-05-29 04:33:01 來源:網(wǎng)站運(yùn)營

Django實(shí)戰(zhàn)教程: 開發(fā)餐廳在線點(diǎn)評網(wǎng)站(1):小編我最喜歡寫Django的基礎(chǔ)知識,尤其是一個(gè)一個(gè)細(xì)小的知識點(diǎn)。因?yàn)槲蚁嘈艧o論你是新手還是高手,熟練地掌握基礎(chǔ)知識才能在實(shí)際Web開發(fā)項(xiàng)目中游刃有余。然而我們學(xué)習(xí)Django的最終目的還是應(yīng)用,今天小編我就帶你用Django開發(fā)一個(gè)餐廳在線點(diǎn)評的APP,也算應(yīng)讀者的要求。如果你對本文中的代碼閱讀起來還感覺有點(diǎn)吃力,建議關(guān)注我的微信公眾號,點(diǎn)擊經(jīng)典原創(chuàng)閱讀Django基礎(chǔ)(1)到(12)。如果對代碼有任何問題或不理解,可以在評論區(qū)留言。




總體思路

我們要開發(fā)一個(gè)餐廳點(diǎn)評網(wǎng)站(APP),具體包括以下幾個(gè)功能性頁面。




如果匿名用戶查看餐廳列表和詳情時(shí),它們會被要求先登錄后再創(chuàng)建餐廳或給餐廳添加評論。我們預(yù)期的效果如下圖所示。本教程分2部分,本文僅介紹前4個(gè)功能性頁面。










項(xiàng)目開發(fā)環(huán)境

Django 2.0 + Python 3.5 + SQLite。因?yàn)槲覀冃枰蟼黠@示圖片,所以請確保你已通過pip安裝python的pillow圖片庫。




項(xiàng)目配置settings.py

我們通過python manage.py startapp myrestaurants創(chuàng)建一個(gè)叫myrestaurants的APP,把它加到settings.py里INSATLLED_APP里去,如下所示。users是對Django自帶AUTH User的擴(kuò)展應(yīng)用。如果不清楚,請閱讀這里

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.staticfiles', 'django.contrib.sites', 'myrestaurants', 'users',]因?yàn)槲覀円玫届o態(tài)文件如css和圖片,我們需要在settings.py里設(shè)置STATIC_URL和MEDIA。用戶上傳的圖片會放在/media/文件夾里。

STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"), ]# specify media root for user uploaded files,MEDIA_ROOT = os.path.join(BASE_DIR, 'media')MEDIA_URL = '/media/'整個(gè)項(xiàng)目的urls.py如下所示。我們把myrestaurants的urls.py也加進(jìn)去了。別忘了在結(jié)尾部分加static配置。

from django.conf.urls import url, includefrom django.contrib import adminfrom django.conf import settingsfrom django.conf.urls.static import staticurlpatterns = [ url(r'^myrestaurants/', include('myrestaurants.urls')), url(r'^admin/', admin.site.urls), url(r'^accounts/', include('users.urls')),] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


模型models.py

對于Django而言,能設(shè)計(jì)一個(gè)良好的models,我們已經(jīng)成功了一半。在本例中我們創(chuàng)建了Restuarant, Dish和Review的模型。因?yàn)槲覀冊谝晥D中會應(yīng)用Django的通用視圖,所以我們的模型里還需要定義get_abosolute_url。Django的CreateView和UpdateView在完成對象的創(chuàng)建或編輯后會自動跳轉(zhuǎn)到這個(gè)絕對url。

from django.db import modelsfrom django.contrib.auth.models import Userfrom datetime import datefrom django.urls import reverseclass Restaurant(models.Model): name = models.TextField() address = models.TextField(blank=True, default='') telephone = models.TextField(blank=True, default='') url = models.URLField(blank=True, null=True) user = models.ForeignKey(User, default=1, on_delete=models.CASCADE) date = models.DateField(default=date.today) def __str__(self): return self.name def get_absolute_url(self): return reverse('myrestaurants:restaurant_detail', args=[str(self.id)])class Dish(models.Model): name = models.TextField() description = models.TextField(blank=True, default='') price = models.DecimalField('USD amount', max_digits=8, decimal_places=2, blank=True, null=True) user = models.ForeignKey(User, default=1, on_delete=models.CASCADE) date = models.DateField(default=date.today) image = models.ImageField(upload_to="myrestaurants", blank=True, null=True) restaurant = models.ForeignKey(Restaurant, null=True, related_name='dishes', on_delete=models.CASCADE) def __str__(self): return self.name def get_absolute_url(self): return reverse('myrestaurants:dish_detail', args=[str(self.restaurant.id), str(self.id)])# This Abstract Review can be used to create RestaurantReview and DishReviewclass Review(models.Model): RATING_CHOICES = ((1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five')) rating = models.PositiveSmallIntegerField('Rating (stars)', blank=False, default=3, choices=RATING_CHOICES) comment = models.TextField(blank=True, null=True) user = models.ForeignKey(User, default=1, on_delete=models.CASCADE) date = models.DateField(default=date.today) class Meta: abstract = Trueclass RestaurantReview(Review): restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE, related_name="reviews") def __str__(self): return "{} review".format(self.restaurant.name)


URLConf配置urls.py

每個(gè)path都對應(yīng)一個(gè)視圖,一個(gè)命名的url和我們本文剛開始介紹的一個(gè)功能性頁面。本文中包含了4個(gè)urls。我們在查看餐廳詳情和編輯餐廳信息的url中傳遞了pk(餐廳id)作為參數(shù)。

from django.urls import path, re_pathfrom . import views# namespaceapp_name = 'myrestaurants'urlpatterns = [# 查看餐廳列表 path('', views.RestaurantList.as_view(), name='restaurant_list'),# 查看餐廳詳情, 如/myrestaurants/restaurant/1/ re_path(r'^restaurant/(?P<pk>/d+)/$', views.RestaurantDetail.as_view(), name='restaurant_detail'),# 創(chuàng)建餐廳, 如:/myrestaurants/restaurant/create/ re_path(r'^restaurant/create/$', views.RestaurantCreate.as_view(), name='restaurant_create'),# 編輯餐廳詳情, 如: /myrestaurants/restaurant/1/edit/ re_path(r'^restaurant/(?P<pk>/d+)/edit/$', views.RestaurantEdit.as_view(), name='restaurant_edit'),]


視圖views.py

為了簡化開發(fā),本例中使用了Django自帶的通用視圖。我們使用ListView來顯示餐廳列表,使用DetailView來顯示餐廳詳情,使用CreateView來創(chuàng)建餐廳,使用UpdateView來編輯餐廳信息。如果你對通用視圖不了解,請閱讀下文:

# Create your views here.from django.http import HttpResponseRedirectfrom django.shortcuts import get_object_or_404, renderfrom django.urls import reversefrom django.views.generic import DetailView, ListView, UpdateViewfrom django.views.generic.edit import CreateViewfrom .models import RestaurantReview, Restaurant, Dishfrom .forms import RestaurantForm, DishFormclass RestaurantList(ListView): queryset = Restaurant.objects.all().order_by('-date') context_object_name = 'latest_restaurant_list' template_name = 'myrestaurants/restaurant_list.html'class RestaurantDetail(DetailView): model = Restaurant template_name = 'myrestaurants/restaurant_detail.html' def get_context_data(self, **kwargs): context = super(RestaurantDetail, self).get_context_data(**kwargs) context['RATING_CHOICES'] = RestaurantReview.RATING_CHOICES return contextclass RestaurantCreate(CreateView): model = Restaurant template_name = 'myrestaurants/form.html' form_class = RestaurantForm # Associate form.instance.user with self.request.user def form_valid(self, form): form.instance.user = self.request.user return super(RestaurantCreate, self).form_valid(form)class RestaurantEdit(UpdateView): model = Restaurant template_name = 'myrestaurants/form.html' form_class = RestaurantForm重要知識點(diǎn):




表單forms.py

創(chuàng)建和編輯對象時(shí)需要用到表單,我們的表單如下所示。我們在前端表單里移除了user,而采用后臺添加的方式。我們添加了widget和labels。添加widget的目的時(shí)為了定制用戶輸入控件(比如URLInput),并給其添加css樣式(因?yàn)閎oostrap表單需要form-control這個(gè)樣式)。

from django.forms import ModelForm, TextInput, URLInput, ClearableFileInputfrom .models import Restaurant, Dishclass RestaurantForm(ModelForm): class Meta: model = Restaurant exclude = ('user', 'date',) widgets = { 'name': TextInput(attrs={'class': 'form-control'}), 'address': TextInput(attrs={'class': 'form-control'}), 'telephone': TextInput(attrs={'class': 'form-control'}), 'url': URLInput(attrs={'class': 'form-control'}), } labels = { 'name': '名稱', 'address': '地址', 'telephone': '電話', 'url': '網(wǎng)站', }


模板文件

我們在目錄中創(chuàng)建templates/myrestaurants/目錄,添加如下html模板。

# restaurant_list.html

{% extends "myrestaurants/base.html" %}{% block content %}<h3>餐廳列表</h3><ul> {% for restaurant in latest_restaurant_list %} <li><a href="{% url 'myrestaurants:restaurant_detail' restaurant.id %}"> {{ restaurant.name }}</a></li> {% empty %}<li>對不起,沒有餐廳點(diǎn)評。</li> {% endfor %}</ul> {% if request.user.is_authenticated %}<p><span class="glyphicon glyphicon-plus"></span> <a href="{% url 'myrestaurants:restaurant_create' %}">添加餐廳</a></p> {% else %}<p>請<a href="{% url 'users:login' %}?next={% url 'myrestaurants:restaurant_create' %}">登錄</a>后添加餐廳。</p> {% endif %}{% endblock %}重要知識點(diǎn):

# restaurant_detail.html

{% extends "myrestaurants/base.html" %}{% block content %}<h3> {{ restaurant.name }} {% if request.user == restaurant.user %} (<a href="{% url 'myrestaurants:restaurant_edit' restaurant.id %}">修改</a>) {% endif %}</h3><h4>地址</h4><p> {{ restaurant.address }}, <br/> {{ restaurant.telephone }}</p><h4>菜單 {% if request.user.is_authenticated %} (<a href="{% url 'myrestaurants:dish_create' restaurant.id %}">添加</a>) {% endif %}</h4><ul> {% for dish in restaurant.dishes.all %} <li><a href="{% url 'myrestaurants:dish_detail' restaurant.id dish.id %}"> {{ dish.name }}</a> - {{ dish.price }}元</li> {% empty %}<li>對不起,該餐廳還沒有菜肴。</li> {% endfor %}</ul><h4>用戶點(diǎn)評</h4>{% if restaurant.reviews.all %} {% for review in restaurant.reviews.all %} <p>{{ review.rating}}星, {{ review.user }}點(diǎn)評, {{ review.date | date:"Y-m-d" }}</p> <p>{{ review.comment }}</p> {% endfor %}{% else %}<p>目前還沒有用戶點(diǎn)評。</p>{% endif %}<h4>添加點(diǎn)評</h4>{% if request.user.is_authenticated %}<form action="{% url 'myrestaurants:review_create' restaurant.id %}" method="post"> {% csrf_token %} <p>評論</p> <textarea name="comment" id="comment"></textarea> <p>評分</p> <p> {% for rate in RATING_CHOICES %} <input type="radio" name="rating" id="rating{{ forloop.counter }}" value="{{ rate.0 }}" /> <label for="choice{{ forloop.counter }}">{{ rate.0 }}星</label> <br/> {% endfor %} </p> <input type="submit" value="提交" /></form>{% else %}<p>請先<a href="{% url 'users:login' %}?next={% firstof request.path '/' %}">登錄</a>再評論。</p>{% endif %}{% endblock %}重要知識點(diǎn):

# form.html

注意: 創(chuàng)建餐廳和編輯餐廳,我們使用了同樣一個(gè)模板。

{% extends "myrestaurants/base.html" %}{% block content %}<form action="" method="post" enctype="multipart/form-data" > {% csrf_token %} {% for hidden_field in form.hidden_fields %} {{ hidden_field }}{% endfor %}{% if form.non_field_errors %} <div class="alert alert-danger" role="alert"> {% for error in form.non_field_errors %} {{ error }} {% endfor %} </div>{% endif %}{% for field in form.visible_fields %} <div class="form-group"> {{ field.label_tag }} {{ field }} {% if field.help_text %} <small class="form-text text-muted">{{ field.help_text }}</small> {% endif %} </div>{% endfor %} <input type="submit" value="提交"/></form>{% endblock %}# base.html

這個(gè)文件基本上只包括樣式,不包括邏輯,可以不看。

{% load static %}<!DOCTYPE html><html lang="en"><head><title>{% block title %} Django餐廳點(diǎn)評系統(tǒng){% endblock %} </title><meta charset="utf-8"><meta name="keywords" content="{% block keywords %} some keywords{% endblock %} "><meta name="description" content="{% block description %} Django web application example.{% endblock %}"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"><link rel="stylesheet" href="{% static 'myrestaurants/custom.css' %}"></head><body class="bs-docs-home"><nav class="navbar navbar-inverse navbar-static-top bs-docs-nav"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#"><strong>Django餐廳點(diǎn)評APP</strong></a> </div> <div class="collapse navbar-collapse" id="myNavbar"> <ul class="nav navbar-nav navbar-right"> {% if user.is_authenticated %} <li class="dropdown"> <a class="dropdown-toggle btn-green" data-toggle="dropdown" href="#"><span class="glyphicon glyphicon-user"></span> {{ user.username }} <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="{% url 'users:profile' user.id %}">我的賬戶</a></li> <li><a href="{% url 'users:logout' %}">退出登錄</a></li> </ul> </li> {% else %} <li class="dropdown"><a class="dropdown-toggle btn-green" href="{% url 'users:register' %}"><span class="glyphicon glyphicon-user"></span> 注冊</a></li> <li class="dropdown"><a class="dropdown-toggle" href="{% url 'users:login' %}" ><span class="glyphicon glyphicon-log-in"></span> 登錄</a></li> {% endif %} </ul> </div> </div></nav> <!-- Page content of course! --><main id="section1" class="container-fluid"><div class="container"> <div class="row"> <div class="col-sm-12"> <div class="wrapper"> <div class="newsbox"> <div class="container1"> {% block content %} {% if error_message %}<p><strong>{{ error_message}}</strong></p>{% endif %} {% endblock %} </div> </div> </div></div></div> </div> </main><footer class="footer"> {% block footer %}{% endblock %}</footer><!--End of Footer--><!-- Bootstrap core JavaScript================================================== --><script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script></body></html>


查看效果

連續(xù)運(yùn)行python manage.py makemigrations, python manage.py migrate和python manage.py runserver, 打開http://127.0.0.1:8000/myrestaurants/就可以看到以下效果了。




餐廳列表(用戶登錄后跳轉(zhuǎn)到添加餐廳頁面)




創(chuàng)建餐廳(用戶創(chuàng)建餐廳后跳轉(zhuǎn)到餐廳詳情)







餐廳詳情頁面(用戶登錄后才能點(diǎn)評)







用戶登錄后可以修改餐廳信息或提交點(diǎn)評







修改餐廳詳情(每個(gè)登錄用戶只能修改自己創(chuàng)建的餐廳)










小結(jié)

我們利用Django開發(fā)了一個(gè)簡單的餐廳點(diǎn)評網(wǎng)站,實(shí)現(xiàn)了以下4個(gè)標(biāo)黃的功能性頁面。下篇教程中,我們將開發(fā)剩余4個(gè)功能性頁面,歡迎關(guān)注我的微信公眾號獲取更多更新。

http://weixin.qq.com/r/F3STl03E14WrKQn0byGT (二維碼自動識別)



關(guān)鍵詞:餐廳,實(shí)戰(zhàn),教程

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉