프로그래밍 방식으로 Play 스토어에서 앱 업데이트 확인
내 앱을 Google Play 스토어에 올렸습니다. 우리 회사의 많은 고객이 설치했습니다. 앱의 업그레이드 방식에 대한 메커니즘을 이해합니다.
사용자는 자동 업데이트하려는 각 앱에 대해 Playstore 앱에서 자동 업데이트 확인란을 선택해야합니다. 그러나 일부 사용자는 처음부터 확인을 취소했거나 확인하지 않았습니다.
제가 작성한 앱은 간병 산업을위한 것이며 간병인이 홈 케어를 제공하는 데 사용됩니다. 내 고객 중 일부는 1200 명의 간병인이 있습니다. 그들은 전화를 개별적으로 업데이트하기 위해 모든 간병인에게 사무실로 전화해야 할 것입니다. 이것은 분명히 받아 들일 수없는 일입니다.
Play 스토어에 내 앱의 업데이트 된 버전이 있는지 프로그래밍 방식으로 확인할 수있는 방법이 있나요?
사용자가 Play 스토어를 확인하는 앱을 시작할 때마다 실행되는 코드를 가질 수 있나요? 업데이트 된 버전이있는 경우 사용자는 플레이 스토어로 이동할 수 있습니다. 이것은 자동 업데이트를 체크 할 필요가 없다는 것을 의미합니다.
미리 감사드립니다
매트
2019 년 4 월 24 일 업데이트 :
Android는이 문제를 해결할 수있는 기능을 발표했습니다. 인앱 업데이트 API 사용 : https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsummit.html
실물:
내가 아는 한 이것을 지원하는 공식 Google API는 없습니다.
API에서 버전 번호를 가져 오는 것을 고려해야합니다.
외부 API 또는 웹 페이지 (예 : Google Play Store)에 연결하는 대신. API 또는 웹 페이지에서 무언가 변경 될 수있는 위험이 있으므로 현재 앱의 버전 코드가 자신의 API에서 얻은 버전 번호보다 낮은 지 확인해야합니다.
앱을 업데이트하는 경우 앱 버전 번호로 자체 API의 버전을 변경해야합니다.
자신의 웹 사이트 나 API에서 버전 번호로 파일을 만드는 것이 좋습니다. (결국 cronjob을 만들고 버전 업데이트를 자동으로 만들고 문제가 발생하면 알림을 보냅니다)
Google Play 스토어 페이지에서이 값을 가져와야합니다.
<div class="content" itemprop="softwareVersion"> x.x.x </div>
모바일에서 사용되는 버전이 자체 API에 표시된 버전 번호보다 낮은 지 앱에서 확인하십시오.
이상적으로는 알림으로 업데이트해야한다는 표시를 보여줍니다.
할 수있는 일
자체 API를 사용하는 버전 번호
장점 :
- Google Play 스토어의 전체 코드를로드 할 필요가 없습니다 (데이터 / 대역폭 절약).
단점 :
- 사용자가 오프라인 일 수 있으므로 API에 액세스 할 수 없기 때문에 확인이 필요하지 않습니다.
웹 페이지 Google Play 스토어의 버전 번호
장점 :
- API가 필요하지 않습니다.
단점 :
- 사용자가 오프라인 일 수 있으므로 API에 액세스 할 수 없기 때문에 확인이 필요하지 않습니다.
- 이 방법을 사용하면 사용자에게 더 많은 대역폭 / 모바일 데이터 비용이 발생할 수 있습니다.
- Play 스토어 웹 페이지가 변경되어 버전 '리퍼'가 더 이상 작동하지 않을 수 있습니다.
앱 build.gradle 파일에 JSoup 포함 :
dependencies {
compile 'org.jsoup:jsoup:1.8.3'
}
다음과 같은 현재 버전을 얻으십시오.
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
그리고 다음 스레드를 실행하십시오.
private class GetVersionCode extends AsyncTask<Void, String, String> {
@Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=it")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();
return newVersion;
} catch (Exception e) {
return newVersion;
}
}
@Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
if (onlineVersion != null && !onlineVersion.isEmpty()) {
if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
//show dialog
}
}
Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
}
자세한 내용은 http://revisitingandroid.blogspot.in/2016/12/programmatically-check-play-store-for.html을 방문하십시오.
Google이 API를 노출하지 않았기 때문에 Firebase 원격 구성 은 현재로서는 가능하고 안정적인 솔루션이 될 수 있습니다.
단계 1. Firebase 프로젝트를 만들고 프로젝트에 google_play_service.json을 추가합니다.
2. firebase console-> Remote Config에서 'android_latest_version_code'및 'android_latest_version_name'과 같은 키를 만듭니다.
3. 안드로이드 코드
public void initializeFirebase() {
if (FirebaseApp.getApps(mContext).isEmpty()) {
FirebaseApp.initializeApp(mContext, FirebaseOptions.fromResource(mContext));
}
final FirebaseRemoteConfig config = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
config.setConfigSettings(configSettings);
}
현재 버전 이름 및 코드 가져 오기
int playStoreVersionCode = FirebaseRemoteConfig.getInstance().getString(
"android_latest_version_code");
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
int currentAppVersionCode = pInfo.versionCode;
if(playStoreVersionCode>currentAppVersionCode){
//Show update popup or whatever best for you
}
4. 현재 프로덕션 버전 이름과 코드를 사용하여 firebase 'android_latest_version_code'및 'android_latest_version_name'을 최신 상태로 유지합니다.
Firebase 원격 구성은 Android와 IPhone 모두에서 작동합니다.
다음과 같이 수정 하여 현재 Playstore 버전 을 얻을 수 있습니다 JSoup
.
@Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=it")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(7)
.ownText();
return newVersion;
} catch (Exception e) {
return newVersion;
}
}
@Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
Log.d("update", "playstore version " + onlineVersion);
}
@Tarun의 답변이 더 이상 작동하지 않습니다.
있다 AppUpdater의 라이브러리. 포함 방법 :
- 프로젝트 build.gradle에 저장소를 추가합니다 .
allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } }
- 모듈 build.gradle에 라이브러리를 추가하십시오 .
dependencies { compile 'com.github.javiersantos:AppUpdater:2.6.4' }
- 앱의 Manifest에 INTERNET 및 ACCESS_NETWORK_STATE 권한을 추가합니다.
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- 활동에 다음을 추가하십시오.
AppUpdater appUpdater = new AppUpdater(this); appUpdater.start();
@Tarun 답변은 완벽하게 작동했지만 Google Play 웹 사이트의 최근 변경 사항으로 인해 현재는 아닙니다.
@Tarun 대답에서 변경하십시오 ..
class GetVersionCode extends AsyncTask<Void, String, String> {
@Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName() + "&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get();
if (document != null) {
Elements element = document.getElementsContainingOwnText("Current Version");
for (Element ele : element) {
if (ele.siblingElements() != null) {
Elements sibElemets = ele.siblingElements();
for (Element sibElemet : sibElemets) {
newVersion = sibElemet.text();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
@Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
if (onlineVersion != null && !onlineVersion.isEmpty()) {
if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
//show anything
}
}
Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
}
}
그리고 JSoup 라이브러리를 추가하는 것을 잊지 마세요
dependencies {
compile 'org.jsoup:jsoup:1.8.3'}
그리고 Oncreate ()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String currentVersion;
try {
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
new GetVersionCode().execute();
}
그게 다야 .. 이 링크 덕분에
하이브리드 애플리케이션 POV에서 가져옴. 이것은 자바 스크립트 예제입니다. 주 메뉴에 업데이트 사용 가능 바닥 글이 있습니다. 업데이트를 사용할 수있는 경우 (예 : 구성 파일 내의 내 버전 번호가 검색된 버전보다 낮 으면 바닥 글 표시) 그러면 사용자가 업데이트 버튼을 클릭 할 수있는 앱 / 플레이 스토어로 이동합니다.
또한 새로운 데이터 (예 : 릴리스 노트)를 가져 와서이 버전에서 처음 인 경우 로그인시 모달에 표시합니다.
장치 준비에서 상점 URL을 설정하십시오.
if (device.platform == 'iOS')
storeURL = 'https://itunes.apple.com/lookup?bundleId=BUNDLEID';
else
storeURL = 'https://play.google.com/store/apps/details?id=BUNDLEID';
Update Available 메서드는 원하는만큼 자주 실행할 수 있습니다. Mine은 사용자가 홈 화면으로 이동할 때마다 실행됩니다.
function isUpdateAvailable() {
if (device.platform == 'iOS') {
$.ajax(storeURL, {
type: "GET",
cache: false,
dataType: 'json'
}).done(function (data) {
isUpdateAvailable_iOS(data.results[0]);
}).fail(function (jqXHR, textStatus, errorThrown) {
commsErrorHandler(jqXHR, textStatus, false);
});
} else {
$.ajax(storeURL, {
type: "GET",
cache: false
}).done(function (data) {
isUpdateAvailable_Android(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
commsErrorHandler(jqXHR, textStatus, false);
});
}
}
iOS 콜백 : Apple에는 API가 있으므로 쉽게 얻을 수 있습니다.
function isUpdateAvailable_iOS (data) {
var storeVersion = data.version;
var releaseNotes = data.releaseNotes;
// Check store Version Against My App Version ('1.14.3' -> 1143)
var _storeV = parseInt(storeVersion.replace(/\./g, ''));
var _appV = parseInt(appVersion.substring(1).replace(/\./g, ''));
$('#ft-main-menu-btn').off();
if (_storeV > _appV) {
// Update Available
$('#ft-main-menu-btn').text('Update Available');
$('#ft-main-menu-btn').click(function () {
openStore();
});
} else {
$('#ft-main-menu-btn').html(' ');
// Release Notes
settings.updateReleaseNotes('v' + storeVersion, releaseNotes);
}
}
Android Callback : PlayStore를 긁어 내야합니다. 버전이 비교적 쉽게 잡을 수 있고 새로운 기능을 볼 수 있으므로 텍스트 대신 html을 사용하여 서식 (예 : 새 줄 등)을 사용할 수 있습니다.
function isUpdateAvailable_Android(data) {
var html = $(data);
var storeVersion = html.find('div[itemprop=softwareVersion]').text().trim();
var releaseNotes = html.find('.whatsnew')[0].innerHTML;
// Check store Version Against My App Version ('1.14.3' -> 1143)
var _storeV = parseInt(storeVersion.replace(/\./g, ''));
var _appV = parseInt(appVersion.substring(1).replace(/\./g, ''));
$('#ft-main-menu-btn').off();
if (_storeV > _appV) {
// Update Available
$('#ft-main-menu-btn').text('Update Available');
$('#ft-main-menu-btn').click(function () {
openStore();
});
} else {
$('#ft-main-menu-btn').html(' ');
// Release Notes
settings.updateReleaseNotes('v' + storeVersion, releaseNotes);
}
}
오픈 스토어 로직은 간단하지만 완전성을 위해
function openStore() {
var url = 'https://itunes.apple.com/us/app/appname/idUniqueID';
if (device.platform != 'iOS')
url = 'https://play.google.com/store/apps/details?id=appid'
window.open(url, '_system')
}
Play Store 및 App Store가 허용 목록에 있는지 확인합니다.
<access origin="https://itunes.apple.com"/>
<access origin="https://play.google.com"/>
OnCreate 메서드 내부에 코드를 작성합니다.
VersionChecker versionChecker = new VersionChecker();
try {
latestVersion = versionChecker.execute().get();
Toast.makeText(getBaseContext(), latestVersion , Toast.LENGTH_SHORT).show();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
이것은 당신에게 앱의 플레이 스토어 버전을 제공합니다 ..
다음과 같이 앱 버전을 확인해야합니다.
PackageManager manager = getPackageManager();
PackageInfo info = null;
try {
info = manager.getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
assert info != null;
version = info.versionName;
그 후 스토어 버전과 비교하여 자신 만의 업데이트 화면을 설정할 수 있습니다.
if(version.equals(latestVersion)){
Toast.makeText(getBaseContext(), "No Update" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getBaseContext(), "Update" , Toast.LENGTH_SHORT).show();
}
그리고 아래와 같이 VersionChecker.class를 추가하십시오.
공용 클래스 VersionChecker extends AsyncTask {
private String newVersion;
@Override
protected String doInBackground(String... params) {
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + "package name" + "&hl=en")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(7)
.ownText();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
}
Firebase 원격 구성이 더 좋습니다.
- 앱에 새 빌드를 게시 할 필요없이 빠르고 쉽게 애플리케이션을 업데이트합니다.
Android에서 원격 구성 구현
원격 구성 종속성 추가
compile 'com.google.firebase:firebase-config:9.6.0'
완료되면 필요한 경우 애플리케이션 전체에서 FirebaseRemoteConfig 인스턴스에 액세스 할 수 있습니다.
FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
원격 구성 값 검색
boolean someBoolean = firebaseRemoteConfig.getBoolean("some_boolean");
byte[] someArray = firebaseRemoteConfig.getByteArray("some_array");
double someDouble = firebaseRemoteConfig.getDouble("some_double");
long someLong = firebaseRemoteConfig.getLong("some_long");
String appVersion = firebaseRemoteConfig.getString("appVersion");
서버 측 값 가져 오기
firebaseRemoteConfig.fetch(cacheExpiration)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activateFetched();
// We got our config, let's do something with it!
if(appVersion < CurrentVersion){
//show update dialog
}
} else {
// Looks like there was a problem getting the config...
}
}
});
이제 새 버전을 playstore에 업로드했으면 firebase 내에서 버전 번호를 업데이트해야합니다. 이제 새 버전이면 업데이트 대화 상자가 표시됩니다.
최신 버전을보고하는 HTTP URL을 노출하는 서버를 설정 한 다음 AlarmManager를 사용하여 해당 URL을 호출하고 장치의 버전이 최신 버전과 동일한 지 확인합니다. 메시지 또는 알림이 팝업되지 않으면 업그레이드를 위해 시장에 보냅니다.
몇 가지 코드 예제가 있습니다. 사용자가 앱 내에서 최신 앱 버전을 확인하도록 허용하는 방법은 무엇입니까?
JSoup을 사용하는 것 외에도 playStore에서 앱 버전을 가져 오기 위해 패턴 일치를 수행 할 수 있습니다.
Google playstore의 최신 패턴을 일치 시키려면 <div class="BgcNfc">Current Version</div><span class="htlgb"><div><span class="htlgb">X.X.X</span></div>
먼저 위의 노드 시퀀스를 일치시킨 다음 위의 시퀀스에서 버전 값을 가져와야 합니다. 다음은 동일한 코드 스 니펫입니다.
private String getAppVersion(String patternString, String inputString) {
try{
//Create a pattern
Pattern pattern = Pattern.compile(patternString);
if (null == pattern) {
return null;
}
//Match the pattern string in provided string
Matcher matcher = pattern.matcher(inputString);
if (null != matcher && matcher.find()) {
return matcher.group(1);
}
}catch (PatternSyntaxException ex) {
ex.printStackTrace();
}
return null;
}
private String getPlayStoreAppVersion(String appUrlString) {
final String currentVersion_PatternSeq = "<div[^>]*?>Current\\sVersion</div><span[^>]*?>(.*?)><div[^>]*?>(.*?)><span[^>]*?>(.*?)</span>";
final String appVersion_PatternSeq = "htlgb\">([^<]*)</s";
String playStoreAppVersion = null;
BufferedReader inReader = null;
URLConnection uc = null;
StringBuilder urlData = new StringBuilder();
final URL url = new URL(appUrlString);
uc = url.openConnection();
if(uc == null) {
return null;
}
uc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
inReader = new BufferedReader(new InputStreamReader(uc.getInputStream()));
if (null != inReader) {
String str = "";
while ((str = inReader.readLine()) != null) {
urlData.append(str);
}
}
// Get the current version pattern sequence
String versionString = getAppVersion (currentVersion_PatternSeq, urlData.toString());
if(null == versionString){
return null;
}else{
// get version from "htlgb">X.X.X</span>
playStoreAppVersion = getAppVersion (appVersion_PatternSeq, versionString);
}
return playStoreAppVersion;
}
최신 Google Playstore 변경 사항에서도 작동하므로 이것을 통해 해결했습니다. 도움이되기를 바랍니다.
Google은 인앱 업데이트 API를 도입 했습니다.
API는 현재 두 가지 흐름을 지원합니다.
- "즉시"흐름은 사용자가 앱을 사용하기 전에 다운로드에서 업데이트까지 안내하는 전체 화면 사용자 환경입니다.
- '유연한 흐름'을 통해 사용자는 앱을 계속 사용하면서 업데이트를 다운로드 할 수 있습니다.
이를 수행하는 공식 GooglePlay API는 없습니다.
그러나이 비공식 라이브러리 를 사용하여 앱 버전 데이터를 가져올 수 있습니다.
위의 방법이 작동하지 않는 경우 언제든지 http로 앱 페이지에 연결할 수 있습니다 (예 : https://play.google.com/store/apps/details?id=com.shots.android&hl=en ). "현재 버전"필드를 구문 분석합니다.
Jsoup을 사용하여 다음 코드를 시도해 볼 수 있습니다.
String latestVersion = doc.getElementsContainingOwnText("Current Version").parents().first().getAllElements().last().text();
private void CheckUPdate() {
VersionChecker versionChecker = new VersionChecker();
try
{ String appVersionName = BuildConfig.VERSION_NAME;
String mLatestVersionName = versionChecker.execute().get();
if(!appVersionName.equals(mLatestVersionName)){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this);
alertDialog.setTitle("Please update your app");
alertDialog.setMessage("This app version is no longer supported. Please update your app from the Play Store.");
alertDialog.setPositiveButton("UPDATE NOW", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String appPackageName = getPackageName();
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
});
alertDialog.show();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
@SuppressLint("StaticFieldLeak")
public class VersionChecker extends AsyncTask<String, String, String> {
private String newVersion;
@Override
protected String doInBackground(String... params) {
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id="+getPackageName())
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(7)
.ownText();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
}
지금 그 방법이 작동하는지 확인했습니다.
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + AcMainPage.this.getPackageName() + "&hl=it")
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get()
.select(".hAyfc .htlgb")
.get(5)
.ownText();
Google은 인앱 업데이트 API를 도입했습니다. 이를 사용하여 사용자에게 애플리케이션 내부에서 앱을 업데이트하도록 요청할 수 있습니다. 사용자가 동의하면 최신 앱을 직접 다운로드하고 playstore로 리디렉션하지 않고 설치할 수 있습니다. 자세한 내용은 아래 링크를 참조하십시오.
Google은 인앱 업데이트 기능 ( https://developer.android.com/guide/app-bundle/in-app-updates )을 도입 했으며 Lollipop +에서 작동하며 사용자에게 멋진 업데이트를 요청할 수있는 기능을 제공합니다. 대화 상자 (유연) 또는 필수 전체 화면 메시지 (즉시).
여기에 어떻게 유연한의 업데이트는 다음과 같이 표시됩니다
여기 https://stackoverflow.com/a/56808529/5502121 에서 내 대답을 확인 하여 유연 하고 즉시 업데이트 흐름 을 구현하는 전체 샘플 코드를 얻을 수 있습니다 . 도움이 되었기를 바랍니다.
참고 URL : https://stackoverflow.com/questions/25201349/programmatically-check-play-store-for-app-updates
'programing' 카테고리의 다른 글
단일 필드를 선택하는 장고 모델 (0) | 2020.11.04 |
---|---|
pip 요구 사항 파일을 사용하여 패키지를 제거하고 설치하려면 어떻게해야합니까? (0) | 2020.11.04 |
실험적 :: 파일 시스템 링커 오류 (0) | 2020.11.04 |
MySQL과 다른 PostgreSQL GROUP BY? (0) | 2020.11.04 |
프록시 뒤에 file_get_contents? (0) | 2020.11.03 |